From b7272bdf66f9afe096c66d1c138f72fc68fa05e9 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Thu, 15 Apr 2021 10:42:47 +1000 Subject: [PATCH 01/13] Increase TTL & remove PoW --- .../libsession/messaging/messages/Message.kt | 2 +- .../control/ClosedGroupControlMessage.kt | 4 ++-- .../messages/control/ConfigurationMessage.kt | 1 - .../sending_receiving/MessageSender.kt | 8 ++----- .../org/session/libsession/snode/SnodeAPI.kt | 23 +++++++++++-------- .../session/libsession/snode/SnodeMessage.kt | 10 ++++---- 6 files changed, 23 insertions(+), 25 deletions(-) diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt index 6f2a916351..ef60aaa83e 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt @@ -15,7 +15,7 @@ abstract class Message { var groupPublicKey: String? = null var openGroupServerMessageID: Long? = null - open val ttl: Long = 2 * 24 * 60 * 60 * 1000 + open val ttl: Long = 14 * 24 * 60 * 60 * 1000 open val isSelfSendValid: Boolean = false // validation diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupControlMessage.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupControlMessage.kt index c02cfc4c19..fa6544fc2a 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupControlMessage.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupControlMessage.kt @@ -19,8 +19,8 @@ class ClosedGroupControlMessage() : ControlMessage() { override val ttl: Long = run { when (kind) { - is Kind.EncryptionKeyPair -> return@run 4 * 24 * 60 * 60 * 1000 - else -> return@run 2 * 24 * 60 * 60 * 1000 + is Kind.EncryptionKeyPair -> 14 * 24 * 60 * 60 * 1000 + else -> 14 * 24 * 60 * 60 * 1000 } } diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ConfigurationMessage.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ConfigurationMessage.kt index fe06cc6c01..2fbf13588f 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ConfigurationMessage.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ConfigurationMessage.kt @@ -87,7 +87,6 @@ class ConfigurationMessage(var closedGroups: List, var openGroups: } } - override val ttl: Long = 4 * 24 * 60 * 60 * 1000 override val isSelfSendValid: Boolean = true companion object { diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt index 225c38b7da..eac8acb32f 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt @@ -31,7 +31,6 @@ import org.session.libsession.messaging.sending_receiving.attachments.Attachment import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview as SignalLinkPreview import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel as SignalQuote - object MessageSender { // Error @@ -147,15 +146,12 @@ object MessageSender { is Destination.OpenGroup -> throw Error.PreconditionFailure("Destination should not be open groups!") } val wrappedMessage = MessageWrapper.wrap(kind, message.sentTimestamp!!, senderPublicKey, ciphertext) - // Calculate proof of work + // Send the result if (destination is Destination.Contact && message is VisibleMessage && !isSelfSend) { SnodeConfiguration.shared.broadcaster.broadcast("calculatingPoW", message.sentTimestamp!!) } - val recipient = message.recipient!! val base64EncodedData = Base64.encodeBytes(wrappedMessage) - val nonce = ProofOfWork.calculate(base64EncodedData, recipient, message.sentTimestamp!!, message.ttl.toInt()) ?: throw Error.ProofOfWorkCalculationFailed - // Send the result - val snodeMessage = SnodeMessage(recipient, base64EncodedData, message.ttl, message.sentTimestamp!!, nonce) + val snodeMessage = SnodeMessage(message.recipient!!, base64EncodedData, message.ttl, message.sentTimestamp!!) if (destination is Destination.Contact && message is VisibleMessage && !isSelfSend) { SnodeConfiguration.shared.broadcaster.broadcast("sendingMessage", message.sentTimestamp!!) } diff --git a/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt b/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt index 9be9db1d29..9f8d417ed3 100644 --- a/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt +++ b/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt @@ -12,6 +12,7 @@ import org.session.libsignal.service.loki.api.utilities.HTTP import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol import org.session.libsignal.service.loki.utilities.Broadcaster import org.session.libsignal.service.loki.utilities.prettifiedDescription +import org.session.libsignal.service.loki.utilities.removing05PrefixIfNeeded import org.session.libsignal.service.loki.utilities.retryIfNeeded import org.session.libsignal.utilities.* import org.session.libsignal.utilities.logging.Log @@ -37,16 +38,18 @@ object SnodeAPI { // use port 4433 if API level can handle network security config and enforce pinned certificates private val seedPort = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) 443 else 4433 - private val seedNodePool: Set = setOf( - "https://storage.seed1.loki.network:$seedPort", - "https://storage.seed3.loki.network:$seedPort", - "https://public.loki.foundation:$seedPort" - ) - internal val snodeFailureThreshold = 4 + private val seedNodePool by lazy { + if (useTestnet) { + setOf( "http://public.loki.foundation:38157" ) + } else { + setOf( "https://storage.seed1.loki.network:$seedPort", "https://storage.seed3.loki.network:$seedPort", "https://public.loki.foundation:$seedPort" ) + } + } + private val snodeFailureThreshold = 4 private val targetSwarmSnodeCount = 2 - private val useOnionRequests = true + internal val useTestnet = false internal var powDifficulty = 1 // Error @@ -164,7 +167,7 @@ object SnodeAPI { cachedSwarmCopy.addAll(cachedSwarm) return task { cachedSwarmCopy } } else { - val parameters = mapOf( "pubKey" to publicKey ) + val parameters = mapOf( "pubKey" to if (useTestnet) publicKey.removing05PrefixIfNeeded() else publicKey ) return getRandomSnode().bind { invoke(Snode.Method.GetSwarm, it, publicKey, parameters) }.map(sharedContext) { @@ -177,7 +180,7 @@ object SnodeAPI { fun getRawMessages(snode: Snode, publicKey: String): RawResponsePromise { val lastHashValue = database.getLastMessageHashValue(snode, publicKey) ?: "" - val parameters = mapOf( "pubKey" to publicKey, "lastHash" to lastHashValue ) + val parameters = mapOf( "pubKey" to if (useTestnet) publicKey.removing05PrefixIfNeeded() else publicKey, "lastHash" to lastHashValue ) return invoke(Snode.Method.GetMessages, snode, publicKey, parameters) } @@ -190,7 +193,7 @@ object SnodeAPI { } fun sendMessage(message: SnodeMessage): Promise, Exception> { - val destination = message.recipient + val destination = if (useTestnet) message.recipient.removing05PrefixIfNeeded() else message.recipient return retryIfNeeded(maxRetryCount) { getTargetSnodes(destination).map { swarm -> swarm.map { snode -> diff --git a/libsession/src/main/java/org/session/libsession/snode/SnodeMessage.kt b/libsession/src/main/java/org/session/libsession/snode/SnodeMessage.kt index 558447c549..0a653e400b 100644 --- a/libsession/src/main/java/org/session/libsession/snode/SnodeMessage.kt +++ b/libsession/src/main/java/org/session/libsession/snode/SnodeMessage.kt @@ -1,5 +1,7 @@ package org.session.libsession.snode +import org.session.libsignal.service.loki.utilities.removing05PrefixIfNeeded + data class SnodeMessage( // The hex encoded public key of the recipient. val recipient: String, @@ -8,16 +10,14 @@ data class SnodeMessage( // The time to live for the message in milliseconds. val ttl: Long, // When the proof of work was calculated. - val timestamp: Long, - // The base 64 encoded proof of work. - val nonce: String + val timestamp: Long ) { internal fun toJSON(): Map { return mutableMapOf( - "pubKey" to recipient, + "pubKey" to if (SnodeAPI.useTestnet) recipient.removing05PrefixIfNeeded() else recipient, "data" to data, "ttl" to ttl.toString(), "timestamp" to timestamp.toString(), - "nonce" to nonce) + "nonce" to "") } } From 979c21ccbf229f0fc8d68b83368373182f6b9abf Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Fri, 23 Apr 2021 16:09:47 +1000 Subject: [PATCH 02/13] Fix duplicated API --- .../securesms/ApplicationContext.java | 28 +- .../securesms/loki/activities/PathActivity.kt | 2 +- .../loki/activities/SettingsActivity.kt | 2 +- .../loki/api/BackgroundPollWorker.kt | 12 +- .../loki/api/LokiPushNotificationManager.kt | 8 +- .../securesms/loki/utilities/IP2Country.kt | 2 +- .../securesms/loki/views/PathStatusView.kt | 2 +- .../securesms/mms/PushMediaConstraints.java | 2 +- .../messaging/fileserver/FileServerAPI.kt | 2 +- .../messaging/opengroups/OpenGroupAPI.kt | 4 +- .../sending_receiving/MessageSender.kt | 7 +- .../notifications/PushNotificationAPI.kt | 2 +- .../libsession/snode/OnionRequestAPI.kt | 2 +- .../session/libsession/snode/SnodeMessage.kt | 6 +- .../api/SignalServiceMessageReceiver.java | 13 +- .../libsignal/service/loki/api/DotNetAPI.kt | 252 ---------- .../libsignal/service/loki/api/LokiMessage.kt | 86 ---- .../service/loki/api/PushNotificationAPI.kt | 42 -- .../libsignal/service/loki/api/SnodeAPI.kt | 280 ----------- .../libsignal/service/loki/api/SwarmAPI.kt | 185 ------- .../service/loki/api/crypto/ProofOfWork.kt | 64 --- .../loki/api/fileserver/FileServerAPI.kt | 77 --- .../loki/api/onionrequests/OnionRequestAPI.kt | 460 ------------------ .../onionrequests/OnionRequestEncryption.kt | 95 ---- .../loki/utilities/DownloadUtilities.kt | 88 ---- 25 files changed, 38 insertions(+), 1685 deletions(-) delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/api/DotNetAPI.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/api/LokiMessage.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/api/PushNotificationAPI.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/api/SnodeAPI.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/api/SwarmAPI.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/api/crypto/ProofOfWork.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/api/fileserver/FileServerAPI.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/api/onionrequests/OnionRequestAPI.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/api/onionrequests/OnionRequestEncryption.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/utilities/DownloadUtilities.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 0ebcdc36a7..63215e5294 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -32,12 +32,15 @@ import androidx.multidex.MultiDexApplication; import org.conscrypt.Conscrypt; import org.session.libsession.messaging.MessagingConfiguration; import org.session.libsession.messaging.avatars.AvatarHelper; +import org.session.libsession.messaging.fileserver.FileServerAPI; import org.session.libsession.messaging.jobs.JobQueue; import org.session.libsession.messaging.opengroups.OpenGroupAPI; import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier; +import org.session.libsession.messaging.sending_receiving.notifications.PushNotificationAPI; import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPoller; import org.session.libsession.messaging.sending_receiving.pollers.Poller; import org.session.libsession.messaging.threads.Address; +import org.session.libsession.snode.SnodeAPI; import org.session.libsession.snode.SnodeConfiguration; import org.session.libsession.utilities.IdentityKeyUtil; import org.session.libsession.utilities.SSKEnvironment; @@ -47,10 +50,6 @@ import org.session.libsession.utilities.dynamiclanguage.DynamicLanguageContextWr import org.session.libsession.utilities.dynamiclanguage.LocaleParser; import org.session.libsession.utilities.preferences.ProfileKeyUtil; import org.session.libsignal.service.api.util.StreamDetails; -import org.session.libsignal.service.loki.api.PushNotificationAPI; -import org.session.libsignal.service.loki.api.SnodeAPI; -import org.session.libsignal.service.loki.api.SwarmAPI; -import org.session.libsignal.service.loki.api.fileserver.FileServerAPI; import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol; import org.session.libsignal.service.loki.utilities.mentions.MentionsManager; import org.session.libsignal.utilities.logging.Log; @@ -96,6 +95,7 @@ import org.webrtc.voiceengine.WebRtcAudioUtils; import java.io.File; import java.io.FileInputStream; +import java.io.IOException; import java.security.SecureRandom; import java.security.Security; import java.util.Date; @@ -179,11 +179,8 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc new SessionProtocolImpl(this)); SnodeConfiguration.Companion.configure(apiDB, broadcaster); if (userPublicKey != null) { - SwarmAPI.Companion.configureIfNeeded(apiDB); - SnodeAPI.Companion.configureIfNeeded(userPublicKey, apiDB, broadcaster); MentionsManager.Companion.configureIfNeeded(userPublicKey, threadDB, userDB); } - PushNotificationAPI.Companion.configureIfNeeded(BuildConfig.DEBUG); setUpStorageAPIIfNeeded(); resubmitProfilePictureIfNeeded(); publicChatManager = new PublicChatManager(this); @@ -427,7 +424,6 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc } byte[] userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(this).getPrivateKey().serialize(); LokiAPIDatabaseProtocol apiDB = DatabaseFactory.getLokiAPIDatabase(this); - FileServerAPI.Companion.configure(userPublicKey, userPrivateKey, apiDB); org.session.libsession.messaging.fileserver.FileServerAPI.Companion.configure(userPublicKey, userPrivateKey, apiDB); return true; } @@ -458,13 +454,10 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc String userPublicKey = TextSecurePreferences.getLocalNumber(this); if (userPublicKey == null) return; if (poller != null) { - SnodeAPI.shared.setUserPublicKey(userPublicKey); poller.setUserPublicKey(userPublicKey); return; } LokiAPIDatabase apiDB = DatabaseFactory.getLokiAPIDatabase(this); - SwarmAPI.Companion.configureIfNeeded(apiDB); - SnodeAPI.Companion.configureIfNeeded(userPublicKey, apiDB, broadcaster); poller = new Poller(); closedGroupPoller = new ClosedGroupPoller(); } @@ -503,12 +496,13 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc try { File profilePicture = AvatarHelper.getAvatarFile(this, Address.fromSerialized(userPublicKey)); StreamDetails stream = new StreamDetails(new FileInputStream(profilePicture), "image/jpeg", profilePicture.length()); - FileServerAPI.shared.uploadProfilePicture(FileServerAPI.shared.getServer(), profileKey, stream, () -> { - TextSecurePreferences.setLastProfilePictureUpload(this, new Date().getTime()); - TextSecurePreferences.setProfileAvatarId(this, new SecureRandom().nextInt()); - ProfileKeyUtil.setEncodedProfileKey(this, encodedProfileKey); - return Unit.INSTANCE; - }); + throw new IOException(); +// FileServerAPI.uploadProfilePicture(FileServerAPI.shared.getServer(), profileKey, stream, () -> { +// TextSecurePreferences.setLastProfilePictureUpload(this, new Date().getTime()); +// TextSecurePreferences.setProfileAvatarId(this, new SecureRandom().nextInt()); +// ProfileKeyUtil.setEncodedProfileKey(this, encodedProfileKey); +// return Unit.INSTANCE; +// }); } catch (Exception exception) { // Do nothing } diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/PathActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/PathActivity.kt index 0fc4c3d363..482a276328 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/PathActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/PathActivity.kt @@ -19,12 +19,12 @@ import android.widget.Toast import androidx.annotation.ColorRes import kotlinx.android.synthetic.main.activity_path.* import network.loki.messenger.R +import org.session.libsession.snode.OnionRequestAPI import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.loki.utilities.* import org.thoughtcrime.securesms.loki.views.GlowViewUtilities import org.thoughtcrime.securesms.loki.views.PathDotView import org.session.libsignal.service.loki.api.Snode -import org.session.libsignal.service.loki.api.onionrequests.OnionRequestAPI class PathActivity : PassphraseRequiredActionBarActivity() { private val broadcastReceivers = mutableListOf() diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/SettingsActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/SettingsActivity.kt index 6bd6bb85ac..95d1f446c0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/SettingsActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/SettingsActivity.kt @@ -28,13 +28,13 @@ import nl.komponents.kovenant.functional.bind import nl.komponents.kovenant.task import nl.komponents.kovenant.ui.alwaysUi import org.session.libsession.messaging.avatars.AvatarHelper +import org.session.libsession.messaging.fileserver.FileServerAPI import org.session.libsession.messaging.opengroups.OpenGroupAPI import org.session.libsession.messaging.threads.Address import org.session.libsession.utilities.SSKEnvironment.ProfileManagerProtocol import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.preferences.ProfileKeyUtil import org.session.libsignal.service.api.util.StreamDetails -import org.session.libsignal.service.loki.api.fileserver.FileServerAPI import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.avatar.AvatarSelection diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt index 8476fae3e1..d4bd5ed8d4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt @@ -10,11 +10,12 @@ import nl.komponents.kovenant.functional.map import org.session.libsession.messaging.jobs.MessageReceiveJob import org.session.libsession.messaging.opengroups.OpenGroup import org.session.libsession.messaging.sending_receiving.pollers.OpenGroupPoller +import org.session.libsession.snode.SnodeAPI import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsignal.service.loki.api.SnodeAPI import org.session.libsignal.utilities.logging.Log import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.database.DatabaseFactory +import java.io.IOException import java.util.concurrent.TimeUnit class BackgroundPollWorker(val context: Context, params: WorkerParameters) : Worker(context, params) { @@ -70,10 +71,11 @@ class BackgroundPollWorker(val context: Context, params: WorkerParameters) : Wor // Private chats val userPublicKey = TextSecurePreferences.getLocalNumber(context)!! - val privateChatsPromise = SnodeAPI.shared.getMessages(userPublicKey).map { envelopes -> - envelopes.map { envelope -> - MessageReceiveJob(envelope.toByteArray(), false).executeAsync() - } + val privateChatsPromise = SnodeAPI.getMessages(userPublicKey).map { envelopes -> + throw IOException() +// envelopes.map { envelope -> +// MessageReceiveJob(envelope.toByteArray(), false).executeAsync() +// } } promises.addAll(privateChatsPromise.get()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/api/LokiPushNotificationManager.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/api/LokiPushNotificationManager.kt index db2789985f..905a58461b 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/api/LokiPushNotificationManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/api/LokiPushNotificationManager.kt @@ -3,12 +3,12 @@ package org.thoughtcrime.securesms.loki.api import android.content.Context import nl.komponents.kovenant.functional.map import okhttp3.* +import org.session.libsession.messaging.sending_receiving.notifications.PushNotificationAPI +import org.session.libsession.snode.OnionRequestAPI import org.thoughtcrime.securesms.database.DatabaseFactory import org.session.libsession.utilities.TextSecurePreferences import org.session.libsignal.utilities.logging.Log import org.session.libsignal.utilities.JsonUtil -import org.session.libsignal.service.loki.api.PushNotificationAPI -import org.session.libsignal.service.loki.api.onionrequests.OnionRequestAPI import org.session.libsignal.service.loki.utilities.retryIfNeeded object LokiPushNotificationManager { @@ -16,10 +16,10 @@ object LokiPushNotificationManager { private val tokenExpirationInterval = 12 * 60 * 60 * 1000 private val server by lazy { - PushNotificationAPI.shared.server + PushNotificationAPI.server } private val pnServerPublicKey by lazy { - PushNotificationAPI.pnServerPublicKey + PushNotificationAPI.serverPublicKey } enum class ClosedGroupOperation { diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/IP2Country.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/IP2Country.kt index 7ebc9e2cb7..855ca52240 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/IP2Country.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/IP2Country.kt @@ -7,7 +7,7 @@ import android.content.IntentFilter import androidx.localbroadcastmanager.content.LocalBroadcastManager import org.session.libsignal.utilities.logging.Log import com.opencsv.CSVReader -import org.session.libsignal.service.loki.api.onionrequests.OnionRequestAPI +import org.session.libsession.snode.OnionRequestAPI import org.session.libsignal.utilities.ThreadUtils import java.io.File import java.io.FileOutputStream diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/views/PathStatusView.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/views/PathStatusView.kt index 7f8611458e..6990849306 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/views/PathStatusView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/views/PathStatusView.kt @@ -11,9 +11,9 @@ import android.util.AttributeSet import android.view.View import androidx.annotation.ColorInt import network.loki.messenger.R +import org.session.libsession.snode.OnionRequestAPI import org.thoughtcrime.securesms.loki.utilities.getColorWithID import org.thoughtcrime.securesms.loki.utilities.toPx -import org.session.libsignal.service.loki.api.onionrequests.OnionRequestAPI class PathStatusView : View { private val broadcastReceivers = mutableListOf() diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/PushMediaConstraints.java b/app/src/main/java/org/thoughtcrime/securesms/mms/PushMediaConstraints.java index 3d5ef96399..4bfcbfd24d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/PushMediaConstraints.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/PushMediaConstraints.java @@ -2,7 +2,7 @@ package org.thoughtcrime.securesms.mms; import android.content.Context; -import org.session.libsignal.service.loki.api.fileserver.FileServerAPI; +import org.session.libsession.messaging.fileserver.FileServerAPI; public class PushMediaConstraints extends MediaConstraints { diff --git a/libsession/src/main/java/org/session/libsession/messaging/fileserver/FileServerAPI.kt b/libsession/src/main/java/org/session/libsession/messaging/fileserver/FileServerAPI.kt index 37230d79d8..c0ae724d44 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/fileserver/FileServerAPI.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/fileserver/FileServerAPI.kt @@ -4,10 +4,10 @@ import nl.komponents.kovenant.Promise import nl.komponents.kovenant.functional.map import okhttp3.Request import org.session.libsession.messaging.utilities.DotNetAPI +import org.session.libsession.snode.OnionRequestAPI import org.session.libsignal.utilities.logging.Log import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.JsonUtil -import org.session.libsignal.service.loki.api.onionrequests.OnionRequestAPI import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol import org.session.libsignal.service.loki.utilities.* import java.net.URL diff --git a/libsession/src/main/java/org/session/libsession/messaging/opengroups/OpenGroupAPI.kt b/libsession/src/main/java/org/session/libsession/messaging/opengroups/OpenGroupAPI.kt index 6c35888f7b..f7b1fd56b2 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/opengroups/OpenGroupAPI.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/opengroups/OpenGroupAPI.kt @@ -8,12 +8,12 @@ import nl.komponents.kovenant.then import org.session.libsession.messaging.MessagingConfiguration import org.session.libsession.messaging.fileserver.FileServerAPI import org.session.libsession.messaging.utilities.DotNetAPI -import org.session.libsignal.service.loki.utilities.DownloadUtilities import org.session.libsignal.service.loki.utilities.retryIfNeeded import org.session.libsignal.utilities.* import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.logging.Log import java.io.ByteArrayOutputStream +import java.io.IOException import java.text.SimpleDateFormat import java.util.* @@ -316,7 +316,7 @@ object OpenGroupAPI: DotNetAPI() { Log.d("Loki", "Downloading open group profile picture from \"$url\".") val outputStream = ByteArrayOutputStream() try { - DownloadUtilities.downloadFile(outputStream, url, FileServerAPI.maxFileSize, null) + throw IOException(); Log.d("Loki", "Open group profile picture was successfully loaded from \"$url\"") return outputStream.toByteArray() } catch (e: Exception) { diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt index 225c38b7da..b6b4d6788c 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt @@ -23,7 +23,6 @@ import org.session.libsession.snode.SnodeMessage import org.session.libsession.utilities.SSKEnvironment import org.session.libsignal.service.internal.push.PushTransportDetails import org.session.libsignal.service.internal.push.SignalServiceProtos -import org.session.libsignal.service.loki.api.crypto.ProofOfWork import org.session.libsignal.service.loki.utilities.hexEncodedPublicKey import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.logging.Log @@ -151,11 +150,9 @@ object MessageSender { if (destination is Destination.Contact && message is VisibleMessage && !isSelfSend) { SnodeConfiguration.shared.broadcaster.broadcast("calculatingPoW", message.sentTimestamp!!) } - val recipient = message.recipient!! - val base64EncodedData = Base64.encodeBytes(wrappedMessage) - val nonce = ProofOfWork.calculate(base64EncodedData, recipient, message.sentTimestamp!!, message.ttl.toInt()) ?: throw Error.ProofOfWorkCalculationFailed // Send the result - val snodeMessage = SnodeMessage(recipient, base64EncodedData, message.ttl, message.sentTimestamp!!, nonce) + val base64EncodedData = Base64.encodeBytes(wrappedMessage) + val snodeMessage = SnodeMessage(message.recipient!!, base64EncodedData, message.ttl, message.sentTimestamp!!) if (destination is Destination.Contact && message is VisibleMessage && !isSelfSend) { SnodeConfiguration.shared.broadcaster.broadcast("sendingMessage", message.sentTimestamp!!) } diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/PushNotificationAPI.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/PushNotificationAPI.kt index d1b2310207..ed0f771498 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/PushNotificationAPI.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/PushNotificationAPI.kt @@ -6,8 +6,8 @@ import okhttp3.MediaType import okhttp3.Request import okhttp3.RequestBody import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.snode.OnionRequestAPI import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsignal.service.loki.api.onionrequests.OnionRequestAPI import org.session.libsignal.service.loki.utilities.retryIfNeeded import org.session.libsignal.utilities.JsonUtil import org.session.libsignal.utilities.logging.Log diff --git a/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt b/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt index 20f1fc8d04..3c4b3e9711 100644 --- a/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt +++ b/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt @@ -6,12 +6,12 @@ import nl.komponents.kovenant.deferred import nl.komponents.kovenant.functional.bind import nl.komponents.kovenant.functional.map import okhttp3.Request +import org.session.libsession.messaging.fileserver.FileServerAPI import org.session.libsession.utilities.AESGCM import org.session.libsignal.utilities.logging.Log import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.* import org.session.libsignal.service.loki.api.Snode -import org.session.libsignal.service.loki.api.fileserver.FileServerAPI import org.session.libsignal.service.loki.api.utilities.* import org.session.libsession.utilities.AESGCM.EncryptionResult import org.session.libsignal.utilities.ThreadUtils diff --git a/libsession/src/main/java/org/session/libsession/snode/SnodeMessage.kt b/libsession/src/main/java/org/session/libsession/snode/SnodeMessage.kt index 558447c549..5d9c49a8d5 100644 --- a/libsession/src/main/java/org/session/libsession/snode/SnodeMessage.kt +++ b/libsession/src/main/java/org/session/libsession/snode/SnodeMessage.kt @@ -8,9 +8,7 @@ data class SnodeMessage( // The time to live for the message in milliseconds. val ttl: Long, // When the proof of work was calculated. - val timestamp: Long, - // The base 64 encoded proof of work. - val nonce: String + val timestamp: Long ) { internal fun toJSON(): Map { return mutableMapOf( @@ -18,6 +16,6 @@ data class SnodeMessage( "data" to data, "ttl" to ttl.toString(), "timestamp" to timestamp.toString(), - "nonce" to nonce) + "nonce" to "") } } diff --git a/libsignal/src/main/java/org/session/libsignal/service/api/SignalServiceMessageReceiver.java b/libsignal/src/main/java/org/session/libsignal/service/api/SignalServiceMessageReceiver.java index 8effb24b34..250d9730a9 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/api/SignalServiceMessageReceiver.java +++ b/libsignal/src/main/java/org/session/libsignal/service/api/SignalServiceMessageReceiver.java @@ -12,7 +12,6 @@ import org.session.libsignal.service.api.crypto.ProfileCipherInputStream; import org.session.libsignal.service.api.messages.SignalServiceAttachment.ProgressListener; import org.session.libsignal.service.api.messages.SignalServiceAttachmentPointer; import org.session.libsignal.service.api.messages.SignalServiceDataMessage; -import org.session.libsignal.service.loki.utilities.DownloadUtilities; import java.io.File; import java.io.FileInputStream; @@ -46,8 +45,7 @@ public class SignalServiceMessageReceiver { public InputStream retrieveProfileAvatar(String path, File destination, byte[] profileKey, int maxSizeBytes) throws IOException { - DownloadUtilities.downloadFile(destination, path, maxSizeBytes, null); - return new ProfileCipherInputStream(new FileInputStream(destination), profileKey); + throw new IOException(); } /** @@ -65,13 +63,6 @@ public class SignalServiceMessageReceiver { public InputStream retrieveAttachment(SignalServiceAttachmentPointer pointer, File destination, int maxSizeBytes, ProgressListener listener) throws IOException, InvalidMessageException { - // Loki - Fetch attachment - if (pointer.getUrl().isEmpty()) throw new InvalidMessageException("Missing attachment URL."); - DownloadUtilities.downloadFile(destination, pointer.getUrl(), maxSizeBytes, listener); - - // Loki - Assume we're retrieving an attachment for an open group server if the digest is not set - if (!pointer.getDigest().isPresent()) { return new FileInputStream(destination); } - - return AttachmentCipherInputStream.createForAttachment(destination, pointer.getSize().or(0), pointer.getKey(), pointer.getDigest().get()); + throw new IOException(); } } diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/DotNetAPI.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/DotNetAPI.kt deleted file mode 100644 index 044afa6301..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/DotNetAPI.kt +++ /dev/null @@ -1,252 +0,0 @@ -package org.session.libsignal.service.loki.api - -import nl.komponents.kovenant.Promise -import nl.komponents.kovenant.functional.bind -import nl.komponents.kovenant.functional.map -import nl.komponents.kovenant.then -import okhttp3.MediaType -import okhttp3.MultipartBody -import okhttp3.Request -import okhttp3.RequestBody -import org.session.libsignal.utilities.logging.Log -import org.session.libsignal.utilities.DiffieHellman -import org.session.libsignal.service.api.crypto.ProfileCipherOutputStream -import org.session.libsignal.service.api.push.exceptions.NonSuccessfulResponseCodeException -import org.session.libsignal.service.api.push.exceptions.PushNetworkException -import org.session.libsignal.service.api.util.StreamDetails -import org.session.libsignal.service.internal.push.ProfileAvatarData -import org.session.libsignal.service.internal.push.PushAttachmentData -import org.session.libsignal.service.internal.push.http.DigestingRequestBody -import org.session.libsignal.service.internal.push.http.ProfileCipherOutputStreamFactory -import org.session.libsignal.utilities.Base64 -import org.session.libsignal.utilities.Hex -import org.session.libsignal.utilities.JsonUtil -import org.session.libsignal.service.loki.api.fileserver.FileServerAPI -import org.session.libsignal.service.loki.api.onionrequests.OnionRequestAPI -import org.session.libsignal.service.loki.api.utilities.HTTP -import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol -import org.session.libsignal.service.loki.utilities.removing05PrefixIfNeeded -import org.session.libsignal.service.loki.utilities.retryIfNeeded -import org.session.libsignal.utilities.recover -import java.util.* - -/** - * Base class that provides utilities for .NET based APIs. - */ -open class LokiDotNetAPI(internal val userPublicKey: String, private val userPrivateKey: ByteArray, private val apiDatabase: LokiAPIDatabaseProtocol) { - - internal enum class HTTPVerb { GET, PUT, POST, DELETE, PATCH } - - companion object { - private val authTokenRequestCache = hashMapOf>() - } - - public data class UploadResult(val id: Long, val url: String, val digest: ByteArray?) - - public fun getAuthToken(server: String): Promise { - val token = apiDatabase.getAuthToken(server) - if (token != null) { return Promise.of(token) } - // Avoid multiple token requests to the server by caching - var promise = authTokenRequestCache[server] - if (promise == null) { - promise = requestNewAuthToken(server).bind { submitAuthToken(it, server) }.then { newToken -> - apiDatabase.setAuthToken(server, newToken) - newToken - }.always { - authTokenRequestCache.remove(server) - } - authTokenRequestCache[server] = promise - } - return promise - } - - private fun requestNewAuthToken(server: String): Promise { - Log.d("Loki", "Requesting auth token for server: $server.") - val parameters: Map = mapOf( "pubKey" to userPublicKey ) - return execute(HTTPVerb.GET, server, "loki/v1/get_challenge", false, parameters).map(SnodeAPI.sharedContext) { json -> - try { - val base64EncodedChallenge = json["cipherText64"] as String - val challenge = Base64.decode(base64EncodedChallenge) - val base64EncodedServerPublicKey = json["serverPubKey64"] as String - var serverPublicKey = Base64.decode(base64EncodedServerPublicKey) - // Discard the "05" prefix if needed - if (serverPublicKey.count() == 33) { - val hexEncodedServerPublicKey = Hex.toStringCondensed(serverPublicKey) - serverPublicKey = Hex.fromStringCondensed(hexEncodedServerPublicKey.removing05PrefixIfNeeded()) - } - // The challenge is prefixed by the 16 bit IV - val tokenAsData = DiffieHellman.decrypt(challenge, serverPublicKey, userPrivateKey) - val token = tokenAsData.toString(Charsets.UTF_8) - token - } catch (exception: Exception) { - Log.d("Loki", "Couldn't parse auth token for server: $server.") - throw exception - } - } - } - - private fun submitAuthToken(token: String, server: String): Promise { - Log.d("Loki", "Submitting auth token for server: $server.") - val parameters = mapOf( "pubKey" to userPublicKey, "token" to token ) - return execute(HTTPVerb.POST, server, "loki/v1/submit_challenge", false, parameters, isJSONRequired = false).map { token } - } - - internal fun execute(verb: HTTPVerb, server: String, endpoint: String, isAuthRequired: Boolean = true, parameters: Map = mapOf(), isJSONRequired: Boolean = true): Promise, Exception> { - fun execute(token: String?): Promise, Exception> { - val sanitizedEndpoint = endpoint.removePrefix("/") - var url = "$server/$sanitizedEndpoint" - if (verb == HTTPVerb.GET || verb == HTTPVerb.DELETE) { - val queryParameters = parameters.map { "${it.key}=${it.value}" }.joinToString("&") - if (queryParameters.isNotEmpty()) { url += "?$queryParameters" } - } - var request = Request.Builder().url(url) - if (isAuthRequired) { - if (token == null) { throw IllegalStateException() } - request = request.header("Authorization", "Bearer $token") - } - when (verb) { - HTTPVerb.GET -> request = request.get() - HTTPVerb.DELETE -> request = request.delete() - else -> { - val parametersAsJSON = JsonUtil.toJson(parameters) - val body = RequestBody.create(MediaType.get("application/json"), parametersAsJSON) - when (verb) { - HTTPVerb.PUT -> request = request.put(body) - HTTPVerb.POST -> request = request.post(body) - HTTPVerb.PATCH -> request = request.patch(body) - else -> throw IllegalStateException() - } - } - } - val serverPublicKeyPromise = if (server == FileServerAPI.shared.server) Promise.of(FileServerAPI.fileServerPublicKey) - else FileServerAPI.shared.getPublicKeyForOpenGroupServer(server) - return serverPublicKeyPromise.bind { serverPublicKey -> - OnionRequestAPI.sendOnionRequest(request.build(), server, serverPublicKey, isJSONRequired = isJSONRequired).recover { exception -> - if (exception is HTTP.HTTPRequestFailedException) { - val statusCode = exception.statusCode - if (statusCode == 401 || statusCode == 403) { - apiDatabase.setAuthToken(server, null) - throw SnodeAPI.Error.TokenExpired - } - } - throw exception - } - } - } - return if (isAuthRequired) { - getAuthToken(server).bind { execute(it) } - } else { - execute(null) - } - } - - internal fun getUserProfiles(publicKeys: Set, server: String, includeAnnotations: Boolean): Promise>, Exception> { - val parameters = mapOf( "include_user_annotations" to includeAnnotations.toInt(), "ids" to publicKeys.joinToString { "@$it" } ) - return execute(HTTPVerb.GET, server, "users", parameters = parameters).map { json -> - val data = json["data"] as? List> - if (data == null) { - Log.d("Loki", "Couldn't parse user profiles for: $publicKeys from: $json.") - throw SnodeAPI.Error.ParsingFailed - } - data!! // For some reason the compiler can't infer that this can't be null at this point - } - } - - internal fun setSelfAnnotation(server: String, type: String, newValue: Any?): Promise, Exception> { - val annotation = mutableMapOf( "type" to type ) - if (newValue != null) { annotation["value"] = newValue } - val parameters = mapOf( "annotations" to listOf( annotation ) ) - return execute(HTTPVerb.PATCH, server, "users/me", parameters = parameters) - } - - @Throws(PushNetworkException::class, NonSuccessfulResponseCodeException::class) - fun uploadAttachment(server: String, attachment: PushAttachmentData): UploadResult { - // This function mimics what Signal does in PushServiceSocket - val contentType = "application/octet-stream" - val file = DigestingRequestBody(attachment.data, attachment.outputStreamFactory, contentType, attachment.dataSize, attachment.listener) - Log.d("Loki", "File size: ${attachment.dataSize} bytes.") - val body = MultipartBody.Builder() - .setType(MultipartBody.FORM) - .addFormDataPart("type", "network.loki") - .addFormDataPart("Content-Type", contentType) - .addFormDataPart("content", UUID.randomUUID().toString(), file) - .build() - val request = Request.Builder().url("$server/files").post(body) - return upload(server, request) { json -> // Retrying is handled by AttachmentUploadJob - val data = json["data"] as? Map<*, *> - if (data == null) { - Log.d("Loki", "Couldn't parse attachment from: $json.") - throw SnodeAPI.Error.ParsingFailed - } - val id = data["id"] as? Long ?: (data["id"] as? Int)?.toLong() ?: (data["id"] as? String)?.toLong() - val url = data["url"] as? String - if (id == null || url == null || url.isEmpty()) { - Log.d("Loki", "Couldn't parse upload from: $json.") - throw SnodeAPI.Error.ParsingFailed - } - UploadResult(id, url, file.transmittedDigest) - }.get() - } - - @Throws(PushNetworkException::class, NonSuccessfulResponseCodeException::class) - fun uploadProfilePicture(server: String, key: ByteArray, profilePicture: StreamDetails, setLastProfilePictureUpload: () -> Unit): UploadResult { - val profilePictureUploadData = ProfileAvatarData(profilePicture.stream, ProfileCipherOutputStream.getCiphertextLength(profilePicture.length), profilePicture.contentType, ProfileCipherOutputStreamFactory(key)) - val file = DigestingRequestBody(profilePictureUploadData.data, profilePictureUploadData.outputStreamFactory, - profilePictureUploadData.contentType, profilePictureUploadData.dataLength, null) - val body = MultipartBody.Builder() - .setType(MultipartBody.FORM) - .addFormDataPart("type", "network.loki") - .addFormDataPart("Content-Type", "application/octet-stream") - .addFormDataPart("content", UUID.randomUUID().toString(), file) - .build() - val request = Request.Builder().url("$server/files").post(body) - return retryIfNeeded(4) { - upload(server, request) { json -> - val data = json["data"] as? Map<*, *> - if (data == null) { - Log.d("Loki", "Couldn't parse profile picture from: $json.") - throw SnodeAPI.Error.ParsingFailed - } - val id = data["id"] as? Long ?: (data["id"] as? Int)?.toLong() ?: (data["id"] as? String)?.toLong() - val url = data["url"] as? String - if (id == null || url == null || url.isEmpty()) { - Log.d("Loki", "Couldn't parse profile picture from: $json.") - throw SnodeAPI.Error.ParsingFailed - } - setLastProfilePictureUpload() - UploadResult(id, url, file.transmittedDigest) - } - }.get() - } - - @Throws(PushNetworkException::class, NonSuccessfulResponseCodeException::class) - private fun upload(server: String, request: Request.Builder, parse: (Map<*, *>) -> UploadResult): Promise { - val promise: Promise, Exception> - if (server == FileServerAPI.shared.server) { - request.addHeader("Authorization", "Bearer loki") - // Uploads to the Loki File Server shouldn't include any personally identifiable information, so use a dummy auth token - promise = OnionRequestAPI.sendOnionRequest(request.build(), FileServerAPI.shared.server, FileServerAPI.fileServerPublicKey) - } else { - promise = FileServerAPI.shared.getPublicKeyForOpenGroupServer(server).bind { openGroupServerPublicKey -> - getAuthToken(server).bind { token -> - request.addHeader("Authorization", "Bearer $token") - OnionRequestAPI.sendOnionRequest(request.build(), server, openGroupServerPublicKey) - } - } - } - return promise.map { json -> - parse(json) - }.recover { exception -> - if (exception is HTTP.HTTPRequestFailedException) { - val statusCode = exception.statusCode - if (statusCode == 401 || statusCode == 403) { - apiDatabase.setAuthToken(server, null) - } - throw NonSuccessfulResponseCodeException("Request returned with status code ${exception.statusCode}.") - } - throw PushNetworkException(exception) - } - } -} - -private fun Boolean.toInt(): Int { return if (this) 1 else 0 } diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/LokiMessage.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/LokiMessage.kt deleted file mode 100644 index 97e1b4ecf4..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/LokiMessage.kt +++ /dev/null @@ -1,86 +0,0 @@ -package org.session.libsignal.service.loki.api - -import nl.komponents.kovenant.Promise -import nl.komponents.kovenant.deferred -import org.session.libsignal.utilities.logging.Log -import org.session.libsignal.utilities.Base64 -import org.session.libsignal.service.loki.api.crypto.ProofOfWork -import org.session.libsignal.service.loki.utilities.TTLUtilities -import org.session.libsignal.utilities.ThreadUtils -import org.session.libsignal.service.loki.utilities.prettifiedDescription - -internal data class LokiMessage( - /** - * The hex encoded public key of the receiver. - */ - internal val recipientPublicKey: String, - /** - * The content of the message. - */ - internal val data: String, - /** - * The time to live for the message in milliseconds. - */ - internal val ttl: Int, - /** - * Whether this message is a ping. - */ - internal val isPing: Boolean, - /** - * When the proof of work was calculated, if applicable (P2P messages don't require proof of work). - * - * - Note: Expressed as milliseconds since 00:00:00 UTC on 1 January 1970. - */ - internal var timestamp: Long? = null, - /** - * The base 64 encoded proof of work, if applicable (P2P messages don't require proof of work). - */ - internal var nonce: String? = null -) { - - internal companion object { - - internal fun from(message: SignalMessageInfo): LokiMessage? { - try { - val wrappedMessage = MessageWrapper.wrap(message) - val data = Base64.encodeBytes(wrappedMessage) - val destination = message.recipientPublicKey - var ttl = TTLUtilities.fallbackMessageTTL - val messageTTL = message.ttl - if (messageTTL != null && messageTTL != 0) { ttl = messageTTL } - val isPing = message.isPing - return LokiMessage(destination, data, ttl, isPing) - } catch (e: Exception) { - Log.d("Loki", "Failed to convert Signal message to Loki message: ${message.prettifiedDescription()}.") - return null - } - } - } - - @kotlin.ExperimentalUnsignedTypes - internal fun calculatePoW(): Promise { - val deferred = deferred() - // Run PoW in a background thread - ThreadUtils.queue { - val now = System.currentTimeMillis() - val nonce = ProofOfWork.calculate(data, recipientPublicKey, now, ttl) - if (nonce != null ) { - deferred.resolve(copy(nonce = nonce, timestamp = now)) - } else { - deferred.reject(SnodeAPI.Error.ProofOfWorkCalculationFailed) - } - } - return deferred.promise - } - - internal fun toJSON(): Map { - val result = mutableMapOf( "pubKey" to recipientPublicKey, "data" to data, "ttl" to ttl.toString() ) - val timestamp = timestamp - val nonce = nonce - if (timestamp != null && nonce != null) { - result["timestamp"] = timestamp.toString() - result["nonce"] = nonce - } - return result - } -} diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/PushNotificationAPI.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/PushNotificationAPI.kt deleted file mode 100644 index 28c370f503..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/PushNotificationAPI.kt +++ /dev/null @@ -1,42 +0,0 @@ -package org.session.libsignal.service.loki.api - -import nl.komponents.kovenant.functional.map -import okhttp3.* -import org.session.libsignal.utilities.logging.Log -import org.session.libsignal.utilities.JsonUtil -import org.session.libsignal.service.loki.api.onionrequests.OnionRequestAPI -import org.session.libsignal.service.loki.utilities.retryIfNeeded - -public class PushNotificationAPI private constructor(public val server: String) { - - companion object { - private val maxRetryCount = 4 - public val pnServerPublicKey = "642a6585919742e5a2d4dc51244964fbcd8bcab2b75612407de58b810740d049" - - lateinit var shared: PushNotificationAPI - - public fun configureIfNeeded(isDebugMode: Boolean) { - if (::shared.isInitialized) { return; } - val server = if (isDebugMode) "https://live.apns.getsession.org" else "https://live.apns.getsession.org" - shared = PushNotificationAPI(server) - } - } - - public fun notify(messageInfo: SignalMessageInfo) { - val message = LokiMessage.from(messageInfo) ?: return - val parameters = mapOf( "data" to message.data, "send_to" to message.recipientPublicKey ) - val url = "${server}/notify" - val body = RequestBody.create(MediaType.get("application/json"), JsonUtil.toJson(parameters)) - val request = Request.Builder().url(url).post(body) - retryIfNeeded(maxRetryCount) { - OnionRequestAPI.sendOnionRequest(request.build(), server, PushNotificationAPI.pnServerPublicKey, "/loki/v2/lsrpc").map { json -> - val code = json["code"] as? Int - if (code == null || code == 0) { - Log.d("Loki", "[Loki] Couldn't notify PN server due to error: ${json["message"] as? String ?: "null"}.") - } - }.fail { exception -> - Log.d("Loki", "[Loki] Couldn't notify PN server due to error: $exception.") - } - } - } -} diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/SnodeAPI.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/SnodeAPI.kt deleted file mode 100644 index 48972afab9..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/SnodeAPI.kt +++ /dev/null @@ -1,280 +0,0 @@ -package org.session.libsignal.service.loki.api - -import nl.komponents.kovenant.Kovenant -import nl.komponents.kovenant.Promise -import nl.komponents.kovenant.deferred -import nl.komponents.kovenant.functional.bind -import nl.komponents.kovenant.functional.map -import nl.komponents.kovenant.task -import org.session.libsignal.utilities.logging.Log -import org.session.libsignal.service.internal.push.SignalServiceProtos.Envelope -import org.session.libsignal.utilities.Base64 -import org.session.libsignal.service.loki.api.onionrequests.OnionRequestAPI -import org.session.libsignal.service.loki.api.utilities.HTTP -import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol -import org.session.libsignal.service.loki.utilities.* -import org.session.libsignal.utilities.* -import java.net.ConnectException -import java.net.SocketTimeoutException - -class SnodeAPI private constructor(public var userPublicKey: String, public val database: LokiAPIDatabaseProtocol, public val broadcaster: Broadcaster) { - - companion object { - val messageSendingContext = Kovenant.createContext() - val messagePollingContext = Kovenant.createContext() - /** - * For operations that are shared between message sending and message polling. - */ - val sharedContext = Kovenant.createContext() - - // region Initialization - lateinit var shared: SnodeAPI - - fun configureIfNeeded(userHexEncodedPublicKey: String, database: LokiAPIDatabaseProtocol, broadcaster: Broadcaster) { - if (::shared.isInitialized) { return; } - shared = SnodeAPI(userHexEncodedPublicKey, database, broadcaster) - } - // endregion - - // region Settings - private val maxRetryCount = 6 - private val useOnionRequests = true - - internal var powDifficulty = 1 - // endregion - } - - // region Error - sealed class Error(val description: String) : Exception() { - class HTTPRequestFailed(val code: Int) : Error("HTTP request failed with error code: $code.") - object Generic : Error("An error occurred.") - object ResponseBodyMissing: Error("Response body missing.") - object MessageSigningFailed: Error("Failed to sign message.") - /** - * Only applicable to snode targets as proof of work isn't required for P2P messaging. - */ - object ProofOfWorkCalculationFailed : Error("Failed to calculate proof of work.") - object MessageConversionFailed : Error("Failed to convert Signal message to Loki message.") - object ClockOutOfSync : Error("The user's clock is out of sync with the service node network.") - object SnodeMigrated : Error("The snode previously associated with the given public key has migrated to a different swarm.") - object InsufficientProofOfWork : Error("The proof of work is insufficient.") - object TokenExpired : Error("The auth token being used has expired.") - object ParsingFailed : Error("Couldn't parse JSON.") - } - // endregion - - // region Internal API - /** - * `publicKey` is the hex encoded public key of the user the call is associated with. This is needed for swarm cache maintenance. - */ - internal fun invoke(method: Snode.Method, snode: Snode, publicKey: String, parameters: Map): RawResponsePromise { - val url = "${snode.address}:${snode.port}/storage_rpc/v1" - if (useOnionRequests) { - return OnionRequestAPI.sendOnionRequest(method, parameters, snode, publicKey) - } else { - val deferred = deferred, Exception>() - ThreadUtils.queue { - val payload = mapOf( "method" to method.rawValue, "params" to parameters ) - try { - val json = HTTP.execute(HTTP.Verb.POST, url, payload) - deferred.resolve(json) - } catch (exception: Exception) { - if (exception is ConnectException || exception is SocketTimeoutException) { - dropSnodeIfNeeded(snode, publicKey) - } else { - val httpRequestFailedException = exception as? HTTP.HTTPRequestFailedException - if (httpRequestFailedException != null) { - @Suppress("NAME_SHADOWING") val exception = handleSnodeError(httpRequestFailedException.statusCode, httpRequestFailedException.json, snode, publicKey) - return@queue deferred.reject(exception) - } - Log.d("Loki", "Unhandled exception: $exception.") - } - deferred.reject(exception) - } - } - return deferred.promise - } - } - - public fun getRawMessages(snode: Snode, publicKey: String): RawResponsePromise { - val lastHashValue = database.getLastMessageHashValue(snode, publicKey) ?: "" - val parameters = mapOf( "pubKey" to publicKey, "lastHash" to lastHashValue ) - return invoke(Snode.Method.GetMessages, snode, publicKey, parameters) - } - // endregion - - // region Public API - fun getMessages(publicKey: String): MessageListPromise { - return retryIfNeeded(maxRetryCount) { - SwarmAPI.shared.getSingleTargetSnode(publicKey).bind(messagePollingContext) { snode -> - getRawMessages(snode, publicKey).map(messagePollingContext) { parseRawMessagesResponse(it, snode, publicKey) } - } - } - } - - @kotlin.ExperimentalUnsignedTypes - fun sendSignalMessage(message: SignalMessageInfo): Promise, Exception> { - val lokiMessage = LokiMessage.from(message) ?: return task { throw Error.MessageConversionFailed } - val destination = lokiMessage.recipientPublicKey - fun broadcast(event: String) { - val dayInMs = 86400000 - if (message.ttl != dayInMs && message.ttl != 4 * dayInMs) { return } - broadcaster.broadcast(event, message.timestamp) - } - broadcast("calculatingPoW") - return lokiMessage.calculatePoW().bind { lokiMessageWithPoW -> - broadcast("contactingNetwork") - retryIfNeeded(maxRetryCount) { - SwarmAPI.shared.getTargetSnodes(destination).map { swarm -> - swarm.map { snode -> - broadcast("sendingMessage") - val parameters = lokiMessageWithPoW.toJSON() - retryIfNeeded(maxRetryCount) { - invoke(Snode.Method.SendMessage, snode, destination, parameters).map { rawResponse -> - val json = rawResponse as? Map<*, *> - val powDifficulty = json?.get("difficulty") as? Int - if (powDifficulty != null) { - if (powDifficulty != SnodeAPI.powDifficulty && powDifficulty < 100) { - Log.d("Loki", "Setting proof of work difficulty to $powDifficulty (snode: $snode).") - SnodeAPI.powDifficulty = powDifficulty - } - } else { - Log.d("Loki", "Failed to update proof of work difficulty from: ${rawResponse.prettifiedDescription()}.") - } - rawResponse - } - } - }.toSet() - } - } - } - } - // endregion - - // region Parsing - - // The parsing utilities below use a best attempt approach to parsing; they warn for parsing failures but don't throw exceptions. - - public fun parseRawMessagesResponse(rawResponse: RawResponse, snode: Snode, publicKey: String): List { - val messages = rawResponse["messages"] as? List<*> - if (messages != null) { - updateLastMessageHashValueIfPossible(snode, publicKey, messages) - val newRawMessages = removeDuplicates(publicKey, messages) - return parseEnvelopes(newRawMessages) - } else { - return listOf() - } - } - - private fun updateLastMessageHashValueIfPossible(snode: Snode, publicKey: String, rawMessages: List<*>) { - val lastMessageAsJSON = rawMessages.lastOrNull() as? Map<*, *> - val hashValue = lastMessageAsJSON?.get("hash") as? String - val expiration = lastMessageAsJSON?.get("expiration") as? Int - if (hashValue != null) { - database.setLastMessageHashValue(snode, publicKey, hashValue) - } else if (rawMessages.isNotEmpty()) { - Log.d("Loki", "Failed to update last message hash value from: ${rawMessages.prettifiedDescription()}.") - } - } - - private fun removeDuplicates(publicKey: String, rawMessages: List<*>): List<*> { - val receivedMessageHashValues = database.getReceivedMessageHashValues(publicKey)?.toMutableSet() ?: mutableSetOf() - return rawMessages.filter { rawMessage -> - val rawMessageAsJSON = rawMessage as? Map<*, *> - val hashValue = rawMessageAsJSON?.get("hash") as? String - if (hashValue != null) { - val isDuplicate = receivedMessageHashValues.contains(hashValue) - receivedMessageHashValues.add(hashValue) - database.setReceivedMessageHashValues(publicKey, receivedMessageHashValues) - !isDuplicate - } else { - Log.d("Loki", "Missing hash value for message: ${rawMessage?.prettifiedDescription()}.") - false - } - } - } - - private fun parseEnvelopes(rawMessages: List<*>): List { - return rawMessages.mapNotNull { rawMessage -> - val rawMessageAsJSON = rawMessage as? Map<*, *> - val base64EncodedData = rawMessageAsJSON?.get("data") as? String - val data = base64EncodedData?.let { Base64.decode(it) } - if (data != null) { - try { - MessageWrapper.unwrap(data) - } catch (e: Exception) { - Log.d("Loki", "Failed to unwrap data for message: ${rawMessage.prettifiedDescription()}.") - null - } - } else { - Log.d("Loki", "Failed to decode data for message: ${rawMessage?.prettifiedDescription()}.") - null - } - } - } - // endregion - - // region Error Handling - private fun dropSnodeIfNeeded(snode: Snode, publicKey: String? = null) { - val oldFailureCount = SwarmAPI.shared.snodeFailureCount[snode] ?: 0 - val newFailureCount = oldFailureCount + 1 - SwarmAPI.shared.snodeFailureCount[snode] = newFailureCount - Log.d("Loki", "Couldn't reach snode at $snode; setting failure count to $newFailureCount.") - if (newFailureCount >= SwarmAPI.snodeFailureThreshold) { - Log.d("Loki", "Failure threshold reached for: $snode; dropping it.") - if (publicKey != null) { - SwarmAPI.shared.dropSnodeFromSwarmIfNeeded(snode, publicKey) - } - SwarmAPI.shared.snodePool = SwarmAPI.shared.snodePool.toMutableSet().minus(snode).toSet() - Log.d("Loki", "Snode pool count: ${SwarmAPI.shared.snodePool.count()}.") - SwarmAPI.shared.snodeFailureCount[snode] = 0 - } - } - - internal fun handleSnodeError(statusCode: Int, json: Map<*, *>?, snode: Snode, publicKey: String? = null): Exception { - when (statusCode) { - 400, 500, 503 -> { // Usually indicates that the snode isn't up to date - dropSnodeIfNeeded(snode, publicKey) - return Error.HTTPRequestFailed(statusCode) - } - 406 -> { - Log.d("Loki", "The user's clock is out of sync with the service node network.") - broadcaster.broadcast("clockOutOfSync") - return Error.ClockOutOfSync - } - 421 -> { - // The snode isn't associated with the given public key anymore - if (publicKey != null) { - Log.d("Loki", "Invalidating swarm for: $publicKey.") - SwarmAPI.shared.dropSnodeFromSwarmIfNeeded(snode, publicKey) - } else { - Log.d("Loki", "Got a 421 without an associated public key.") - } - return Error.SnodeMigrated - } - 432 -> { - // The PoW difficulty is too low - val powDifficulty = json?.get("difficulty") as? Int - if (powDifficulty != null && powDifficulty < 100) { - Log.d("Loki", "Setting proof of work difficulty to $powDifficulty (snode: $snode).") - SnodeAPI.powDifficulty = powDifficulty - } else { - Log.d("Loki", "Failed to update proof of work difficulty.") - } - return Error.InsufficientProofOfWork - } - else -> { - dropSnodeIfNeeded(snode, publicKey) - Log.d("Loki", "Unhandled response code: ${statusCode}.") - return Error.Generic - } - } - } - // endregion -} - -// region Convenience -typealias RawResponse = Map<*, *> -typealias MessageListPromise = Promise, Exception> -typealias RawResponsePromise = Promise -// endregion diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/SwarmAPI.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/SwarmAPI.kt deleted file mode 100644 index 26dbf698e6..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/SwarmAPI.kt +++ /dev/null @@ -1,185 +0,0 @@ -package org.session.libsignal.service.loki.api - -import android.os.Build -import nl.komponents.kovenant.Promise -import nl.komponents.kovenant.deferred -import nl.komponents.kovenant.functional.bind -import nl.komponents.kovenant.functional.map -import nl.komponents.kovenant.task -import org.session.libsignal.service.loki.api.utilities.HTTP -import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol -import org.session.libsignal.service.loki.utilities.getRandomElement -import org.session.libsignal.service.loki.utilities.prettifiedDescription -import org.session.libsignal.service.loki.utilities.retryIfNeeded -import org.session.libsignal.utilities.ThreadUtils -import org.session.libsignal.utilities.logging.Log -import java.security.SecureRandom -import java.util.* - -class SwarmAPI private constructor(private val database: LokiAPIDatabaseProtocol) { - internal var snodeFailureCount: MutableMap = mutableMapOf() - - internal var snodePool: Set - get() = database.getSnodePool() - set(newValue) { database.setSnodePool(newValue) } - - companion object { - - // use port 4433 if API level can handle network security config and enforce pinned certificates - private val seedPort = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) 443 else 4433 - private val seedNodePool: Set = setOf( - "https://storage.seed1.loki.network:$seedPort", - "https://storage.seed3.loki.network:$seedPort", - "https://public.loki.foundation:$seedPort" - ) - - // region Settings - private val minimumSnodePoolCount = 64 - private val minimumSwarmSnodeCount = 2 - private val targetSwarmSnodeCount = 2 - private val maxRetryCount = 6 - - /** - * A snode is kicked out of a swarm and/or the snode pool if it fails this many times. - */ - internal val snodeFailureThreshold = 2 - // endregion - - // region Initialization - lateinit var shared: SwarmAPI - - fun configureIfNeeded(database: LokiAPIDatabaseProtocol) { - if (::shared.isInitialized) { return; } - shared = SwarmAPI(database) - } - // endregion - } - - // region Swarm API - internal fun getRandomSnode(): Promise { - val snodePool = this.snodePool - val lastRefreshDate = database.getLastSnodePoolRefreshDate() - val now = Date() - val needsRefresh = (snodePool.count() < minimumSnodePoolCount) || lastRefreshDate == null || (now.time - lastRefreshDate.time) > 24 * 60 * 60 * 1000 - if (needsRefresh) { - database.setLastSnodePoolRefreshDate(now) - - val target = seedNodePool.random() - val url = "$target/json_rpc" - Log.d("Loki", "Populating snode pool using: $target.") - val parameters = mapOf( - "method" to "get_n_service_nodes", - "params" to mapOf( - "active_only" to true, - "fields" to mapOf( "public_ip" to true, "storage_port" to true, "pubkey_x25519" to true, "pubkey_ed25519" to true ) - ) - ) - val deferred = deferred() - deferred(SnodeAPI.sharedContext) - ThreadUtils.queue { - try { - val json = HTTP.execute(HTTP.Verb.POST, url, parameters, useSeedNodeConnection = true) - val intermediate = json["result"] as? Map<*, *> - val rawSnodes = intermediate?.get("service_node_states") as? List<*> - if (rawSnodes != null) { - @Suppress("NAME_SHADOWING") val snodePool = rawSnodes.mapNotNull { rawSnode -> - val rawSnodeAsJSON = rawSnode as? Map<*, *> - val address = rawSnodeAsJSON?.get("public_ip") as? String - val port = rawSnodeAsJSON?.get("storage_port") as? Int - val ed25519Key = rawSnodeAsJSON?.get("pubkey_ed25519") as? String - val x25519Key = rawSnodeAsJSON?.get("pubkey_x25519") as? String - if (address != null && port != null && ed25519Key != null && x25519Key != null && address != "0.0.0.0") { - Snode("https://$address", port, Snode.KeySet(ed25519Key, x25519Key)) - } else { - Log.d("Loki", "Failed to parse: ${rawSnode?.prettifiedDescription()}.") - null - } - }.toMutableSet() - Log.d("Loki", "Persisting snode pool to database.") - this.snodePool = snodePool - try { - deferred.resolve(snodePool.getRandomElement()) - } catch (exception: Exception) { - Log.d("Loki", "Got an empty snode pool from: $target.") - deferred.reject(SnodeAPI.Error.Generic) - } - } else { - Log.d("Loki", "Failed to update snode pool from: ${(rawSnodes as List<*>?)?.prettifiedDescription()}.") - deferred.reject(SnodeAPI.Error.Generic) - } - } catch (exception: Exception) { - deferred.reject(exception) - } - } - return deferred.promise - } else { - return Promise.of(snodePool.getRandomElement()) - } - } - - public fun getSwarm(publicKey: String): Promise, Exception> { - val cachedSwarm = database.getSwarm(publicKey) - if (cachedSwarm != null && cachedSwarm.size >= minimumSwarmSnodeCount) { - val cachedSwarmCopy = mutableSetOf() // Workaround for a Kotlin compiler issue - cachedSwarmCopy.addAll(cachedSwarm) - return task { cachedSwarmCopy } - } else { - val parameters = mapOf( "pubKey" to publicKey ) - return getRandomSnode().bind { - retryIfNeeded(maxRetryCount) { - SnodeAPI.shared.invoke(Snode.Method.GetSwarm, it, publicKey, parameters) - } - - }.map(SnodeAPI.sharedContext) { - parseSnodes(it).toSet() - }.success { - database.setSwarm(publicKey, it) - } - } - } - - internal fun dropSnodeFromSwarmIfNeeded(snode: Snode, publicKey: String) { - val swarm = database.getSwarm(publicKey)?.toMutableSet() - if (swarm != null && swarm.contains(snode)) { - swarm.remove(snode) - database.setSwarm(publicKey, swarm) - } - } - - internal fun getSingleTargetSnode(publicKey: String): Promise { - // SecureRandom() should be cryptographically secure - return getSwarm(publicKey).map { it.shuffled(SecureRandom()).random() } - } - - internal fun getTargetSnodes(publicKey: String): Promise, Exception> { - // SecureRandom() should be cryptographically secure - return getSwarm(publicKey).map { it.shuffled(SecureRandom()).take(targetSwarmSnodeCount) } - } - // endregion - - // region Parsing - private fun parseSnodes(rawResponse: Any): List { - val json = rawResponse as? Map<*, *> - val rawSnodes = json?.get("snodes") as? List<*> - if (rawSnodes != null) { - return rawSnodes.mapNotNull { rawSnode -> - val rawSnodeAsJSON = rawSnode as? Map<*, *> - val address = rawSnodeAsJSON?.get("ip") as? String - val portAsString = rawSnodeAsJSON?.get("port") as? String - val port = portAsString?.toInt() - val ed25519Key = rawSnodeAsJSON?.get("pubkey_ed25519") as? String - val x25519Key = rawSnodeAsJSON?.get("pubkey_x25519") as? String - if (address != null && port != null && ed25519Key != null && x25519Key != null && address != "0.0.0.0") { - Snode("https://$address", port, Snode.KeySet(ed25519Key, x25519Key)) - } else { - Log.d("Loki", "Failed to parse snode from: ${rawSnode?.prettifiedDescription()}.") - null - } - } - } else { - Log.d("Loki", "Failed to parse snodes from: ${rawResponse.prettifiedDescription()}.") - return listOf() - } - } - // endregion -} diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/crypto/ProofOfWork.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/crypto/ProofOfWork.kt deleted file mode 100644 index f1bfc59cc6..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/crypto/ProofOfWork.kt +++ /dev/null @@ -1,64 +0,0 @@ -package org.session.libsignal.service.loki.api.crypto - -import org.session.libsignal.utilities.logging.Log -import org.session.libsignal.utilities.Base64 -import org.session.libsignal.service.loki.api.SnodeAPI -import java.math.BigInteger -import java.nio.ByteBuffer -import java.security.MessageDigest - -/** - * Based on the desktop messenger's proof of work implementation. For more information, see libloki/proof-of-work.js. - */ -object ProofOfWork { - - // region Settings - private val nonceSize = 8 - // endregion - - // region Implementation - @kotlin.ExperimentalUnsignedTypes - fun calculate(data: String, hexEncodedPublicKey: String, timestamp: Long, ttl: Int): String? { - try { - val sha512 = MessageDigest.getInstance("SHA-512") - val payloadAsString = timestamp.toString() + ttl.toString() + hexEncodedPublicKey + data - val payload = payloadAsString.toByteArray() - val target = determineTarget(ttl, payload.size) - var currentTrialValue = ULong.MAX_VALUE - var nonce: Long = 0 - val initialHash = sha512.digest(payload) - while (currentTrialValue > target) { - nonce += 1 - // This is different from bitmessage's PoW implementation - // newHash = hash(nonce + hash(data)) → hash(nonce + initialHash) - val newHash = sha512.digest(nonce.toByteArray() + initialHash) - currentTrialValue = newHash.sliceArray(0 until nonceSize).toULong() - } - return Base64.encodeBytes(nonce.toByteArray()) - } catch (e: Exception) { - Log.d("Loki", "Couldn't calculate proof of work due to error: $e.") - return null - } - } - - @kotlin.ExperimentalUnsignedTypes - private fun determineTarget(ttl: Int, payloadSize: Int): ULong { - val x1 = BigInteger.valueOf(2).pow(16) - 1.toBigInteger() - val x2 = BigInteger.valueOf(2).pow(64) - 1.toBigInteger() - val size = (payloadSize + nonceSize).toBigInteger() - val ttlInSeconds = (ttl / 1000).toBigInteger() - val x3 = (ttlInSeconds * size) / x1 - val x4 = size + x3 - val x5 = SnodeAPI.powDifficulty.toBigInteger() * x4 - return (x2 / x5).toULong() - } - // endregion -} - -// region Convenience -@kotlin.ExperimentalUnsignedTypes -private fun BigInteger.toULong() = toLong().toULong() -private fun Long.toByteArray() = ByteBuffer.allocate(8).putLong(this).array() -@kotlin.ExperimentalUnsignedTypes -private fun ByteArray.toULong() = ByteBuffer.wrap(this).long.toULong() -// endregion diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/fileserver/FileServerAPI.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/fileserver/FileServerAPI.kt deleted file mode 100644 index 2e63a76564..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/fileserver/FileServerAPI.kt +++ /dev/null @@ -1,77 +0,0 @@ -package org.session.libsignal.service.loki.api.fileserver - -import nl.komponents.kovenant.Promise -import nl.komponents.kovenant.functional.map -import okhttp3.Request -import org.session.libsignal.utilities.logging.Log -import org.session.libsignal.utilities.Base64 -import org.session.libsignal.utilities.JsonUtil -import org.session.libsignal.service.loki.api.LokiDotNetAPI -import org.session.libsignal.service.loki.api.onionrequests.OnionRequestAPI -import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol -import org.session.libsignal.service.loki.utilities.* -import java.net.URL -import java.util.concurrent.ConcurrentHashMap - -class FileServerAPI(public val server: String, userPublicKey: String, userPrivateKey: ByteArray, private val database: LokiAPIDatabaseProtocol) : LokiDotNetAPI(userPublicKey, userPrivateKey, database) { - - companion object { - // region Settings - internal val fileServerPublicKey = "62509D59BDEEC404DD0D489C1E15BA8F94FD3D619B01C1BF48A9922BFCB7311C" - internal val maxRetryCount = 4 - - public val maxFileSize = 10_000_000 // 10 MB - /** - * The file server has a file size limit of `maxFileSize`, which the Service Nodes try to enforce as well. However, the limit applied by the Service Nodes - * is on the **HTTP request** and not the actual file size. Because the file server expects the file data to be base 64 encoded, the size of the HTTP - * request for a given file will be at least `ceil(n / 3) * 4` bytes, where n is the file size in bytes. This is the minimum size because there might also - * be other parameters in the request. On average the multiplier appears to be about 1.5, so when checking whether the file will exceed the file size limit when - * uploading a file we just divide the size of the file by this number. The alternative would be to actually check the size of the HTTP request but that's only - * possible after proof of work has been calculated and the onion request encryption has happened, which takes several seconds. - */ - public val fileSizeORMultiplier = 2 // TODO: It should be possible to set this to 1.5? - public val fileStorageBucketURL = "https://file-static.lokinet.org" - // endregion - - // region Initialization - lateinit var shared: FileServerAPI - - /** - * Must be called before `LokiAPI` is used. - */ - fun configure(userPublicKey: String, userPrivateKey: ByteArray, database: LokiAPIDatabaseProtocol) { - if (Companion::shared.isInitialized) { return } - val server = "https://file.getsession.org" - shared = FileServerAPI(server, userPublicKey, userPrivateKey, database) - } - // endregion - } - - // region Open Group Server Public Key - fun getPublicKeyForOpenGroupServer(openGroupServer: String): Promise { - val publicKey = database.getOpenGroupPublicKey(openGroupServer) - if (publicKey != null && PublicKeyValidation.isValid(publicKey, 64, false)) { - return Promise.of(publicKey) - } else { - val url = "$server/loki/v1/getOpenGroupKey/${URL(openGroupServer).host}" - val request = Request.Builder().url(url) - request.addHeader("Content-Type", "application/json") - request.addHeader("Authorization", "Bearer loki") // Tokenless request; use a dummy token - return OnionRequestAPI.sendOnionRequest(request.build(), server, fileServerPublicKey).map { json -> - try { - val bodyAsString = json["data"] as String - val body = JsonUtil.fromJson(bodyAsString) - val base64EncodedPublicKey = body.get("data").asText() - val prefixedPublicKey = Base64.decode(base64EncodedPublicKey) - val hexEncodedPrefixedPublicKey = prefixedPublicKey.toHexString() - val result = hexEncodedPrefixedPublicKey.removing05PrefixIfNeeded() - database.setOpenGroupPublicKey(openGroupServer, result) - result - } catch (exception: Exception) { - Log.d("Loki", "Couldn't parse open group public key from: $json.") - throw exception - } - } - } - } -} diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/onionrequests/OnionRequestAPI.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/onionrequests/OnionRequestAPI.kt deleted file mode 100644 index efeab36fa4..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/onionrequests/OnionRequestAPI.kt +++ /dev/null @@ -1,460 +0,0 @@ -package org.session.libsignal.service.loki.api.onionrequests - -import nl.komponents.kovenant.Promise -import nl.komponents.kovenant.all -import nl.komponents.kovenant.deferred -import nl.komponents.kovenant.functional.bind -import nl.komponents.kovenant.functional.map -import okhttp3.Request -import org.session.libsignal.utilities.logging.Log -import org.session.libsignal.utilities.Base64 -import org.session.libsignal.utilities.JsonUtil -import org.session.libsignal.service.loki.api.* -import org.session.libsignal.service.loki.api.fileserver.FileServerAPI -import org.session.libsignal.service.loki.api.utilities.* -import org.session.libsignal.service.loki.api.utilities.EncryptionResult -import org.session.libsignal.service.loki.api.utilities.getBodyForOnionRequest -import org.session.libsignal.service.loki.api.utilities.getHeadersForOnionRequest -import org.session.libsignal.service.loki.utilities.* -import org.session.libsignal.utilities.* - -private typealias Path = List - -/** - * See the "Onion Requests" section of [The Session Whitepaper](https://arxiv.org/pdf/2002.04609.pdf) for more information. - */ -public object OnionRequestAPI { - private val pathFailureCount = mutableMapOf() - private val snodeFailureCount = mutableMapOf() - public var guardSnodes = setOf() - public var paths: List // Not a set to ensure we consistently show the same path to the user - get() = SnodeAPI.shared.database.getOnionRequestPaths() - set(newValue) { - if (newValue.isEmpty()) { - SnodeAPI.shared.database.clearOnionRequestPaths() - } else { - SnodeAPI.shared.database.setOnionRequestPaths(newValue) - } - } - - // region Settings - /** - * The number of snodes (including the guard snode) in a path. - */ - private val pathSize = 3 - /** - * The number of times a path can fail before it's replaced. - */ - private val pathFailureThreshold = 1 - /** - * The number of times a snode can fail before it's replaced. - */ - private val snodeFailureThreshold = 1 - /** - * The number of paths to maintain. - */ - public val targetPathCount = 2 // A main path and a backup path for the case where the target snode is in the main path - - /** - * The number of guard snodes required to maintain `targetPathCount` paths. - */ - private val targetGuardSnodeCount - get() = targetPathCount // One per path - // endregion - - class HTTPRequestFailedAtDestinationException(val statusCode: Int, val json: Map<*, *>) - : Exception("HTTP request failed at destination with status code $statusCode.") - class InsufficientSnodesException : Exception("Couldn't find enough snodes to build a path.") - - private data class OnionBuildingResult( - internal val guardSnode: Snode, - internal val finalEncryptionResult: EncryptionResult, - internal val destinationSymmetricKey: ByteArray - ) - - internal sealed class Destination { - class Snode(val snode: org.session.libsignal.service.loki.api.Snode) : Destination() - class Server(val host: String, val target: String, val x25519PublicKey: String) : Destination() - } - - // region Private API - /** - * Tests the given snode. The returned promise errors out if the snode is faulty; the promise is fulfilled otherwise. - */ - private fun testSnode(snode: Snode): Promise { - val deferred = deferred() - ThreadUtils.queue { // No need to block the shared context for this - val url = "${snode.address}:${snode.port}/get_stats/v1" - try { - val json = HTTP.execute(HTTP.Verb.GET, url) - val version = json["version"] as? String - if (version == null) { deferred.reject(Exception("Missing snode version.")); return@queue } - if (version >= "2.0.7") { - deferred.resolve(Unit) - } else { - val message = "Unsupported snode version: $version." - Log.d("Loki", message) - deferred.reject(Exception(message)) - } - } catch (exception: Exception) { - deferred.reject(exception) - } - } - return deferred.promise - } - - /** - * Finds `targetGuardSnodeCount` guard snodes to use for path building. The returned promise errors out if not - * enough (reliable) snodes are available. - */ - private fun getGuardSnodes(reusableGuardSnodes: List): Promise, Exception> { - if (guardSnodes.count() >= targetGuardSnodeCount) { - return Promise.of(guardSnodes) - } else { - Log.d("Loki", "Populating guard snode cache.") - return SwarmAPI.shared.getRandomSnode().bind(SnodeAPI.sharedContext) { // Just used to populate the snode pool - var unusedSnodes = SwarmAPI.shared.snodePool.minus(reusableGuardSnodes) - val reusableGuardSnodeCount = reusableGuardSnodes.count() - if (unusedSnodes.count() < (targetGuardSnodeCount - reusableGuardSnodeCount)) { throw InsufficientSnodesException() } - fun getGuardSnode(): Promise { - val candidate = unusedSnodes.getRandomElementOrNull() - ?: return Promise.ofFail(InsufficientSnodesException()) - unusedSnodes = unusedSnodes.minus(candidate) - Log.d("Loki", "Testing guard snode: $candidate.") - // Loop until a reliable guard snode is found - val deferred = deferred() - testSnode(candidate).success { - deferred.resolve(candidate) - }.fail { - getGuardSnode().success { - deferred.resolve(candidate) - }.fail { exception -> - if (exception is InsufficientSnodesException) { - deferred.reject(exception) - } - } - } - return deferred.promise - } - val promises = (0 until (targetGuardSnodeCount - reusableGuardSnodeCount)).map { getGuardSnode() } - all(promises).map(SnodeAPI.sharedContext) { guardSnodes -> - val guardSnodesAsSet = (guardSnodes + reusableGuardSnodes).toSet() - OnionRequestAPI.guardSnodes = guardSnodesAsSet - guardSnodesAsSet - } - } - } - } - - /** - * Builds and returns `targetPathCount` paths. The returned promise errors out if not - * enough (reliable) snodes are available. - */ - private fun buildPaths(reusablePaths: List): Promise, Exception> { - Log.d("Loki", "Building onion request paths.") - SnodeAPI.shared.broadcaster.broadcast("buildingPaths") - return SwarmAPI.shared.getRandomSnode().bind(SnodeAPI.sharedContext) { // Just used to populate the snode pool - val reusableGuardSnodes = reusablePaths.map { it[0] } - getGuardSnodes(reusableGuardSnodes).map(SnodeAPI.sharedContext) { guardSnodes -> - var unusedSnodes = SwarmAPI.shared.snodePool.minus(guardSnodes).minus(reusablePaths.flatten()) - val reusableGuardSnodeCount = reusableGuardSnodes.count() - val pathSnodeCount = (targetGuardSnodeCount - reusableGuardSnodeCount) * pathSize - (targetGuardSnodeCount - reusableGuardSnodeCount) - if (unusedSnodes.count() < pathSnodeCount) { throw InsufficientSnodesException() } - // Don't test path snodes as this would reveal the user's IP to them - guardSnodes.minus(reusableGuardSnodes).map { guardSnode -> - val result = listOf( guardSnode ) + (0 until (pathSize - 1)).map { - val pathSnode = unusedSnodes.getRandomElement() - unusedSnodes = unusedSnodes.minus(pathSnode) - pathSnode - } - Log.d("Loki", "Built new onion request path: $result.") - result - } - }.map { paths -> - OnionRequestAPI.paths = paths + reusablePaths - SnodeAPI.shared.broadcaster.broadcast("pathsBuilt") - paths - } - } - } - - /** - * Returns a `Path` to be used for building an onion request. Builds new paths as needed. - */ - private fun getPath(snodeToExclude: Snode?): Promise { - if (pathSize < 1) { throw Exception("Can't build path of size zero.") } - val paths = this.paths - val guardSnodes = mutableSetOf() - if (paths.isNotEmpty()) { - guardSnodes.add(paths[0][0]) - if (paths.count() >= 2) { - guardSnodes.add(paths[1][0]) - } - } - OnionRequestAPI.guardSnodes = guardSnodes - fun getPath(paths: List): Path { - if (snodeToExclude != null) { - return paths.filter { !it.contains(snodeToExclude) }.getRandomElement() - } else { - return paths.getRandomElement() - } - } - if (paths.count() >= targetPathCount) { - return Promise.of(getPath(paths)) - } else if (paths.isNotEmpty()) { - if (paths.any { !it.contains(snodeToExclude) }) { - buildPaths(paths) // Re-build paths in the background - return Promise.of(getPath(paths)) - } else { - return buildPaths(paths).map(SnodeAPI.sharedContext) { newPaths -> - getPath(newPaths) - } - } - } else { - return buildPaths(listOf()).map(SnodeAPI.sharedContext) { newPaths -> - getPath(newPaths) - } - } - } - - private fun dropGuardSnode(snode: Snode) { - guardSnodes = guardSnodes.filter { it != snode }.toSet() - } - - private fun dropSnode(snode: Snode) { - // We repair the path here because we can do it sync. In the case where we drop a whole - // path we leave the re-building up to getPath() because re-building the path in that case - // is async. - snodeFailureCount[snode] = 0 - val oldPaths = paths.toMutableList() - val pathIndex = oldPaths.indexOfFirst { it.contains(snode) } - if (pathIndex == -1) { return } - val path = oldPaths[pathIndex].toMutableList() - val snodeIndex = path.indexOf(snode) - if (snodeIndex == -1) { return } - path.removeAt(snodeIndex) - val unusedSnodes = SwarmAPI.shared.snodePool.minus(oldPaths.flatten()) - if (unusedSnodes.isEmpty()) { throw InsufficientSnodesException() } - path.add(unusedSnodes.getRandomElement()) - // Don't test the new snode as this would reveal the user's IP - oldPaths.removeAt(pathIndex) - val newPaths = oldPaths + listOf( path ) - paths = newPaths - } - - private fun dropPath(path: Path) { - pathFailureCount[path] = 0 - val paths = OnionRequestAPI.paths.toMutableList() - val pathIndex = paths.indexOf(path) - if (pathIndex == -1) { return } - paths.removeAt(pathIndex) - OnionRequestAPI.paths = paths - } - - /** - * Builds an onion around `payload` and returns the result. - */ - private fun buildOnionForDestination(payload: Map<*, *>, destination: Destination): Promise { - lateinit var guardSnode: Snode - lateinit var destinationSymmetricKey: ByteArray // Needed by LokiAPI to decrypt the response sent back by the destination - lateinit var encryptionResult: EncryptionResult - val snodeToExclude = when (destination) { - is Destination.Snode -> destination.snode - is Destination.Server -> null - } - return getPath(snodeToExclude).bind(SnodeAPI.sharedContext) { path -> - guardSnode = path.first() - // Encrypt in reverse order, i.e. the destination first - OnionRequestEncryption.encryptPayloadForDestination(payload, destination).bind(SnodeAPI.sharedContext) { r -> - destinationSymmetricKey = r.symmetricKey - // Recursively encrypt the layers of the onion (again in reverse order) - encryptionResult = r - @Suppress("NAME_SHADOWING") var path = path - var rhs = destination - fun addLayer(): Promise { - if (path.isEmpty()) { - return Promise.of(encryptionResult) - } else { - val lhs = Destination.Snode(path.last()) - path = path.dropLast(1) - return OnionRequestEncryption.encryptHop(lhs, rhs, encryptionResult).bind(SnodeAPI.sharedContext) { r -> - encryptionResult = r - rhs = lhs - addLayer() - } - } - } - addLayer() - } - }.map(SnodeAPI.sharedContext) { OnionBuildingResult(guardSnode, encryptionResult, destinationSymmetricKey) } - } - - /** - * Sends an onion request to `destination`. Builds new paths as needed. - */ - private fun sendOnionRequest(destination: Destination, payload: Map<*, *>, isJSONRequired: Boolean = true): Promise, Exception> { - val deferred = deferred, Exception>() - var guardSnode: Snode? = null - buildOnionForDestination(payload, destination).success { result -> - guardSnode = result.guardSnode - val url = "${guardSnode!!.address}:${guardSnode!!.port}/onion_req/v2" - val finalEncryptionResult = result.finalEncryptionResult - val onion = finalEncryptionResult.ciphertext - if (destination is Destination.Server && onion.count().toDouble() > 0.75 * FileServerAPI.maxFileSize.toDouble()) { - Log.d("Loki", "Approaching request size limit: ~${onion.count()} bytes.") - } - @Suppress("NAME_SHADOWING") val parameters = mapOf( - "ephemeral_key" to finalEncryptionResult.ephemeralPublicKey.toHexString() - ) - val body: ByteArray - try { - body = OnionRequestEncryption.encode(onion, parameters) - } catch (exception: Exception) { - return@success deferred.reject(exception) - } - val destinationSymmetricKey = result.destinationSymmetricKey - ThreadUtils.queue { - try { - val json = HTTP.execute(HTTP.Verb.POST, url, body) - val base64EncodedIVAndCiphertext = json["result"] as? String ?: return@queue deferred.reject(Exception("Invalid JSON")) - val ivAndCiphertext = Base64.decode(base64EncodedIVAndCiphertext) - try { - val plaintext = DecryptionUtilities.decryptUsingAESGCM(ivAndCiphertext, destinationSymmetricKey) - try { - @Suppress("NAME_SHADOWING") val json = JsonUtil.fromJson(plaintext.toString(Charsets.UTF_8), Map::class.java) - val statusCode = json["status"] as Int - if (statusCode == 406) { - @Suppress("NAME_SHADOWING") val body = mapOf( "result" to "Your clock is out of sync with the service node network." ) - val exception = HTTPRequestFailedAtDestinationException(statusCode, body) - return@queue deferred.reject(exception) - } else if (json["body"] != null) { - @Suppress("NAME_SHADOWING") val body: Map<*, *> - if (json["body"] is Map<*, *>) { - body = json["body"] as Map<*, *> - } else { - val bodyAsString = json["body"] as String - if (!isJSONRequired) { - body = mapOf( "result" to bodyAsString ) - } else { - body = JsonUtil.fromJson(bodyAsString, Map::class.java) - } - } - if (statusCode != 200) { - val exception = HTTPRequestFailedAtDestinationException(statusCode, body) - return@queue deferred.reject(exception) - } - deferred.resolve(body) - } else { - if (statusCode != 200) { - val exception = HTTPRequestFailedAtDestinationException(statusCode, json) - return@queue deferred.reject(exception) - } - deferred.resolve(json) - } - } catch (exception: Exception) { - deferred.reject(Exception("Invalid JSON: ${plaintext.toString(Charsets.UTF_8)}.")) - } - } catch (exception: Exception) { - deferred.reject(exception) - } - } catch (exception: Exception) { - deferred.reject(exception) - } - } - }.fail { exception -> - deferred.reject(exception) - } - val promise = deferred.promise - promise.fail { exception -> - val path = if (guardSnode != null) paths.firstOrNull { it.contains(guardSnode!!) } else null - if (exception is HTTP.HTTPRequestFailedException) { - fun handleUnspecificError() { - if (path == null) { return } - var pathFailureCount = OnionRequestAPI.pathFailureCount[path] ?: 0 - pathFailureCount += 1 - if (pathFailureCount >= pathFailureThreshold) { - dropGuardSnode(guardSnode!!) - path.forEach { snode -> - @Suppress("ThrowableNotThrown") - SnodeAPI.shared.handleSnodeError(exception.statusCode, exception.json, snode, null) // Intentionally don't throw - } - dropPath(path) - } else { - OnionRequestAPI.pathFailureCount[path] = pathFailureCount - } - } - val json = exception.json - val message = json?.get("result") as? String - val prefix = "Next node not found: " - if (message != null && message.startsWith(prefix)) { - val ed25519PublicKey = message.substringAfter(prefix) - val snode = path?.firstOrNull { it.publicKeySet!!.ed25519Key == ed25519PublicKey } - if (snode != null) { - var snodeFailureCount = OnionRequestAPI.snodeFailureCount[snode] ?: 0 - snodeFailureCount += 1 - if (snodeFailureCount >= snodeFailureThreshold) { - @Suppress("ThrowableNotThrown") - SnodeAPI.shared.handleSnodeError(exception.statusCode, json, snode, null) // Intentionally don't throw - try { - dropSnode(snode) - } catch (exception: Exception) { - handleUnspecificError() - } - } else { - OnionRequestAPI.snodeFailureCount[snode] = snodeFailureCount - } - } else { - handleUnspecificError() - } - } else if (message == "Loki Server error") { - // Do nothing - } else { - handleUnspecificError() - } - } - } - return promise - } - // endregion - - // region Internal API - /** - * Sends an onion request to `snode`. Builds new paths as needed. - */ - internal fun sendOnionRequest(method: Snode.Method, parameters: Map<*, *>, snode: Snode, publicKey: String): Promise, Exception> { - val payload = mapOf( "method" to method.rawValue, "params" to parameters ) - return sendOnionRequest(Destination.Snode(snode), payload).recover { exception -> - @Suppress("NAME_SHADOWING") val exception = exception as? HTTPRequestFailedAtDestinationException ?: throw exception - throw SnodeAPI.shared.handleSnodeError(exception.statusCode, exception.json, snode, publicKey) - } - } - - /** - * Sends an onion request to `server`. Builds new paths as needed. - * - * `publicKey` is the hex encoded public key of the user the call is associated with. This is needed for swarm cache maintenance. - */ - public fun sendOnionRequest(request: Request, server: String, x25519PublicKey: String, target: String = "/loki/v3/lsrpc", isJSONRequired: Boolean = true): Promise, Exception> { - val headers = request.getHeadersForOnionRequest() - val url = request.url() - val urlAsString = url.toString() - val host = url.host() - val endpoint = when { - server.count() < urlAsString.count() -> urlAsString.substringAfter("$server/") - else -> "" - } - val body = request.getBodyForOnionRequest() ?: "null" - val payload = mapOf( - "body" to body, - "endpoint" to endpoint, - "method" to request.method(), - "headers" to headers - ) - val destination = Destination.Server(host, target, x25519PublicKey) - return sendOnionRequest(destination, payload, isJSONRequired).recover { exception -> - Log.d("Loki", "Couldn't reach server: $urlAsString due to error: $exception.") - throw exception - } - } - // endregion -} diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/onionrequests/OnionRequestEncryption.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/onionrequests/OnionRequestEncryption.kt deleted file mode 100644 index 63f1c9636e..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/onionrequests/OnionRequestEncryption.kt +++ /dev/null @@ -1,95 +0,0 @@ -package org.session.libsignal.service.loki.api.onionrequests - -import nl.komponents.kovenant.Promise -import nl.komponents.kovenant.deferred -import org.session.libsignal.utilities.JsonUtil -import org.session.libsignal.service.loki.api.utilities.EncryptionResult -import org.session.libsignal.service.loki.api.utilities.EncryptionUtilities -import org.session.libsignal.utilities.ThreadUtils -import org.session.libsignal.service.loki.utilities.toHexString -import java.nio.Buffer -import java.nio.ByteBuffer -import java.nio.ByteOrder - -object OnionRequestEncryption { - - internal fun encode(ciphertext: ByteArray, json: Map<*, *>): ByteArray { - // The encoding of V2 onion requests looks like: | 4 bytes: size N of ciphertext | N bytes: ciphertext | json as utf8 | - val jsonAsData = JsonUtil.toJson(json).toByteArray() - val ciphertextSize = ciphertext.size - val buffer = ByteBuffer.allocate(Int.SIZE_BYTES) - buffer.order(ByteOrder.LITTLE_ENDIAN) - buffer.putInt(ciphertextSize) - val ciphertextSizeAsData = ByteArray(buffer.capacity()) - // Casting here avoids an issue where this gets compiled down to incorrect byte code. See - // https://github.com/eclipse/jetty.project/issues/3244 for more info - (buffer as Buffer).position(0) - buffer.get(ciphertextSizeAsData) - return ciphertextSizeAsData + ciphertext + jsonAsData - } - - /** - * Encrypts `payload` for `destination` and returns the result. Use this to build the core of an onion request. - */ - internal fun encryptPayloadForDestination(payload: Map<*, *>, destination: OnionRequestAPI.Destination): Promise { - val deferred = deferred() - ThreadUtils.queue { - try { - // Wrapping isn't needed for file server or open group onion requests - when (destination) { - is OnionRequestAPI.Destination.Snode -> { - val snodeX25519PublicKey = destination.snode.publicKeySet!!.x25519Key - val payloadAsData = JsonUtil.toJson(payload).toByteArray() - val plaintext = encode(payloadAsData, mapOf( "headers" to "" )) - val result = EncryptionUtilities.encryptForX25519PublicKey(plaintext, snodeX25519PublicKey) - deferred.resolve(result) - } - is OnionRequestAPI.Destination.Server -> { - val plaintext = JsonUtil.toJson(payload).toByteArray() - val result = EncryptionUtilities.encryptForX25519PublicKey(plaintext, destination.x25519PublicKey) - deferred.resolve(result) - } - } - } catch (exception: Exception) { - deferred.reject(exception) - } - } - return deferred.promise - } - - /** - * Encrypts the previous encryption result (i.e. that of the hop after this one) for this hop. Use this to build the layers of an onion request. - */ - internal fun encryptHop(lhs: OnionRequestAPI.Destination, rhs: OnionRequestAPI.Destination, previousEncryptionResult: EncryptionResult): Promise { - val deferred = deferred() - ThreadUtils.queue { - try { - val payload: MutableMap - when (rhs) { - is OnionRequestAPI.Destination.Snode -> { - payload = mutableMapOf( "destination" to rhs.snode.publicKeySet!!.ed25519Key ) - } - is OnionRequestAPI.Destination.Server -> { - payload = mutableMapOf( "host" to rhs.host, "target" to rhs.target, "method" to "POST" ) - } - } - payload["ephemeral_key"] = previousEncryptionResult.ephemeralPublicKey.toHexString() - val x25519PublicKey: String - when (lhs) { - is OnionRequestAPI.Destination.Snode -> { - x25519PublicKey = lhs.snode.publicKeySet!!.x25519Key - } - is OnionRequestAPI.Destination.Server -> { - x25519PublicKey = lhs.x25519PublicKey - } - } - val plaintext = encode(previousEncryptionResult.ciphertext, payload) - val result = EncryptionUtilities.encryptForX25519PublicKey(plaintext, x25519PublicKey) - deferred.resolve(result) - } catch (exception: Exception) { - deferred.reject(exception) - } - } - return deferred.promise - } -} diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/DownloadUtilities.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/DownloadUtilities.kt deleted file mode 100644 index a582c0fa31..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/DownloadUtilities.kt +++ /dev/null @@ -1,88 +0,0 @@ -package org.session.libsignal.service.loki.utilities - -import okhttp3.HttpUrl -import okhttp3.Request -import org.session.libsignal.utilities.logging.Log -import org.session.libsignal.service.api.messages.SignalServiceAttachment -import org.session.libsignal.service.api.push.exceptions.NonSuccessfulResponseCodeException -import org.session.libsignal.service.api.push.exceptions.PushNetworkException -import org.session.libsignal.utilities.Base64 -import org.session.libsignal.service.loki.api.fileserver.FileServerAPI -import org.session.libsignal.service.loki.api.onionrequests.OnionRequestAPI -import java.io.* - -object DownloadUtilities { - - /** - * Blocks the calling thread. - */ - @JvmStatic - fun downloadFile(destination: File, url: String, maxSize: Int, listener: SignalServiceAttachment.ProgressListener?) { - val outputStream = FileOutputStream(destination) // Throws - var remainingAttempts = 4 - var exception: Exception? = null - while (remainingAttempts > 0) { - remainingAttempts -= 1 - try { - downloadFile(outputStream, url, maxSize, listener) - exception = null - break - } catch (e: Exception) { - exception = e - } - } - if (exception != null) { throw exception } - } - - /** - * Blocks the calling thread. - */ - @JvmStatic - fun downloadFile(outputStream: OutputStream, url: String, maxSize: Int, listener: SignalServiceAttachment.ProgressListener?) { - // We need to throw a PushNetworkException or NonSuccessfulResponseCodeException - // because the underlying Signal logic requires these to work correctly - val oldPrefixedHost = "https://" + HttpUrl.get(url).host() - var newPrefixedHost = oldPrefixedHost - if (oldPrefixedHost.contains(FileServerAPI.fileStorageBucketURL)) { - newPrefixedHost = FileServerAPI.shared.server - } - // Edge case that needs to work: https://file-static.lokinet.org/i1pNmpInq3w9gF3TP8TFCa1rSo38J6UM - // → https://file.getsession.org/loki/v1/f/XLxogNXVEIWHk14NVCDeppzTujPHxu35 - val fileID = url.substringAfter(oldPrefixedHost).substringAfter("/f/") - val sanitizedURL = "$newPrefixedHost/loki/v1/f/$fileID" - val request = Request.Builder().url(sanitizedURL).get() - try { - val serverPublicKey = if (newPrefixedHost.contains(FileServerAPI.shared.server)) FileServerAPI.fileServerPublicKey - else FileServerAPI.shared.getPublicKeyForOpenGroupServer(newPrefixedHost).get() - val json = OnionRequestAPI.sendOnionRequest(request.build(), newPrefixedHost, serverPublicKey, isJSONRequired = false).get() - val result = json["result"] as? String - if (result == null) { - Log.d("Loki", "Couldn't parse attachment from: $json.") - throw PushNetworkException("Missing response body.") - } - val body = Base64.decode(result) - if (body.size > maxSize) { - Log.d("Loki", "Attachment size limit exceeded.") - throw PushNetworkException("Max response size exceeded.") - } - body.inputStream().use { input -> - val buffer = ByteArray(32768) - var count = 0 - var bytes = input.read(buffer) - while (bytes >= 0) { - outputStream.write(buffer, 0, bytes) - count += bytes - if (count > maxSize) { - Log.d("Loki", "Attachment size limit exceeded.") - throw PushNetworkException("Max response size exceeded.") - } - listener?.onAttachmentProgress(body.size.toLong(), count.toLong()) - bytes = input.read(buffer) - } - } - } catch (e: Exception) { - Log.d("Loki", "Couldn't download attachment due to error: $e.") - throw if (e is NonSuccessfulResponseCodeException) e else PushNetworkException(e) - } - } -} From bc66c45bca98a782231e178da63e8b1d96418639 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Mon, 26 Apr 2021 10:26:31 +1000 Subject: [PATCH 03/13] Clean --- .../securesms/ApplicationContext.java | 8 +-- .../sending_receiving/MessageSender.kt | 10 +-- .../sending_receiving/pollers/Poller.kt | 10 +-- .../messaging/utilities/DotNetAPI.kt | 2 +- .../libsession/snode/OnionRequestAPI.kt | 45 ++++++------ .../org/session/libsession/snode/Snode.kt | 7 -- .../org/session/libsession/snode/SnodeAPI.kt | 68 +++++-------------- .../session/libsession/snode/SnodeMessage.kt | 14 ++-- .../{SnodeConfiguration.kt => SnodeModule.kt} | 7 +- .../libsession/snode/StorageProtocol.kt | 1 + 10 files changed, 68 insertions(+), 104 deletions(-) rename libsession/src/main/java/org/session/libsession/snode/{SnodeConfiguration.kt => SnodeModule.kt} (63%) diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 63215e5294..38de09d0e0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -32,16 +32,13 @@ import androidx.multidex.MultiDexApplication; import org.conscrypt.Conscrypt; import org.session.libsession.messaging.MessagingConfiguration; import org.session.libsession.messaging.avatars.AvatarHelper; -import org.session.libsession.messaging.fileserver.FileServerAPI; import org.session.libsession.messaging.jobs.JobQueue; import org.session.libsession.messaging.opengroups.OpenGroupAPI; import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier; -import org.session.libsession.messaging.sending_receiving.notifications.PushNotificationAPI; import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPoller; import org.session.libsession.messaging.sending_receiving.pollers.Poller; import org.session.libsession.messaging.threads.Address; -import org.session.libsession.snode.SnodeAPI; -import org.session.libsession.snode.SnodeConfiguration; +import org.session.libsession.snode.SnodeModule; import org.session.libsession.utilities.IdentityKeyUtil; import org.session.libsession.utilities.SSKEnvironment; import org.session.libsession.utilities.TextSecurePreferences; @@ -96,7 +93,6 @@ import org.webrtc.voiceengine.WebRtcAudioUtils; import java.io.File; import java.io.FileInputStream; import java.io.IOException; -import java.security.SecureRandom; import java.security.Security; import java.util.Date; import java.util.HashSet; @@ -177,7 +173,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc DatabaseFactory.getStorage(this), DatabaseFactory.getAttachmentProvider(this), new SessionProtocolImpl(this)); - SnodeConfiguration.Companion.configure(apiDB, broadcaster); + SnodeModule.Companion.configure(apiDB, broadcaster); if (userPublicKey != null) { MentionsManager.Companion.configureIfNeeded(userPublicKey, threadDB, userDB); } diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt index 8ae61cdee1..bea27664a8 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt @@ -18,7 +18,7 @@ import org.session.libsession.messaging.threads.Address import org.session.libsession.messaging.utilities.MessageWrapper import org.session.libsession.snode.RawResponsePromise import org.session.libsession.snode.SnodeAPI -import org.session.libsession.snode.SnodeConfiguration +import org.session.libsession.snode.SnodeModule import org.session.libsession.snode.SnodeMessage import org.session.libsession.utilities.SSKEnvironment import org.session.libsignal.service.internal.push.PushTransportDetails @@ -82,7 +82,7 @@ object MessageSender { fun handleFailure(error: Exception) { handleFailedMessageSend(message, error) if (destination is Destination.Contact && message is VisibleMessage && !isSelfSend) { - SnodeConfiguration.shared.broadcaster.broadcast("messageFailed", message.sentTimestamp!!) + SnodeModule.shared.broadcaster.broadcast("messageFailed", message.sentTimestamp!!) } deferred.reject(error) } @@ -147,12 +147,12 @@ object MessageSender { val wrappedMessage = MessageWrapper.wrap(kind, message.sentTimestamp!!, senderPublicKey, ciphertext) // Send the result if (destination is Destination.Contact && message is VisibleMessage && !isSelfSend) { - SnodeConfiguration.shared.broadcaster.broadcast("calculatingPoW", message.sentTimestamp!!) + SnodeModule.shared.broadcaster.broadcast("calculatingPoW", message.sentTimestamp!!) } val base64EncodedData = Base64.encodeBytes(wrappedMessage) val snodeMessage = SnodeMessage(message.recipient!!, base64EncodedData, message.ttl, message.sentTimestamp!!) if (destination is Destination.Contact && message is VisibleMessage && !isSelfSend) { - SnodeConfiguration.shared.broadcaster.broadcast("sendingMessage", message.sentTimestamp!!) + SnodeModule.shared.broadcaster.broadcast("sendingMessage", message.sentTimestamp!!) } SnodeAPI.sendMessage(snodeMessage).success { promises: Set -> var isSuccess = false @@ -163,7 +163,7 @@ object MessageSender { if (isSuccess) { return@success } // Succeed as soon as the first promise succeeds isSuccess = true if (destination is Destination.Contact && message is VisibleMessage && !isSelfSend) { - SnodeConfiguration.shared.broadcaster.broadcast("messageSent", message.sentTimestamp!!) + SnodeModule.shared.broadcaster.broadcast("messageSent", message.sentTimestamp!!) } handleSuccessfulMessageSend(message, destination, isSyncMessage) var shouldNotify = (message is VisibleMessage && !isSyncMessage) diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt index 474a2768b5..80db18b7e6 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt @@ -7,7 +7,7 @@ import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.messaging.jobs.MessageReceiveJob import org.session.libsession.messaging.utilities.MessageWrapper import org.session.libsession.snode.SnodeAPI -import org.session.libsession.snode.SnodeConfiguration +import org.session.libsession.snode.SnodeModule import org.session.libsignal.service.loki.api.Snode import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.logging.Log @@ -47,9 +47,9 @@ class Poller { private fun setUpPolling() { if (!hasStarted) { return; } val thread = Thread.currentThread() - SnodeAPI.getSwarm(userPublicKey).bind(SnodeAPI.messagePollingContext) { + SnodeAPI.getSwarm(userPublicKey).bind { usedSnodes.clear() - val deferred = deferred(SnodeAPI.messagePollingContext) + val deferred = deferred() pollNextSnode(deferred) deferred.promise }.always { @@ -63,7 +63,7 @@ class Poller { } private fun pollNextSnode(deferred: Deferred) { - val swarm = SnodeConfiguration.shared.storage.getSwarm(userPublicKey) ?: setOf() + val swarm = SnodeModule.shared.storage.getSwarm(userPublicKey) ?: setOf() val unusedSnodes = swarm.subtract(usedSnodes) if (unusedSnodes.isNotEmpty()) { val index = SecureRandom().nextInt(unusedSnodes.size) @@ -87,7 +87,7 @@ class Poller { private fun poll(snode: Snode, deferred: Deferred): Promise { if (!hasStarted) { return Promise.ofFail(PromiseCanceledException()) } - return SnodeAPI.getRawMessages(snode, userPublicKey).bind(SnodeAPI.messagePollingContext) { rawResponse -> + return SnodeAPI.getRawMessages(snode, userPublicKey).bind { rawResponse -> isCaughtUp = true if (deferred.promise.isDone()) { task { Unit } // The long polling connection has been canceled; don't recurse diff --git a/libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt b/libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt index 0856e43862..7d0af36477 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt @@ -83,7 +83,7 @@ open class DotNetAPI { Log.d("Loki", "Requesting auth token for server: $server.") val userKeyPair = MessagingConfiguration.shared.storage.getUserKeyPair() ?: throw Error.Generic val parameters: Map = mapOf( "pubKey" to userKeyPair.first ) - return execute(HTTPVerb.GET, server, "loki/v1/get_challenge", false, parameters).map(SnodeAPI.sharedContext) { json -> + return execute(HTTPVerb.GET, server, "loki/v1/get_challenge", false, parameters).map { json -> try { val base64EncodedChallenge = json["cipherText64"] as String val challenge = Base64.decode(base64EncodedChallenge) diff --git a/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt b/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt index 3c4b3e9711..2cf6b18e6a 100644 --- a/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt +++ b/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt @@ -17,6 +17,7 @@ import org.session.libsession.utilities.AESGCM.EncryptionResult import org.session.libsignal.utilities.ThreadUtils import org.session.libsession.utilities.getBodyForOnionRequest import org.session.libsession.utilities.getHeadersForOnionRequest +import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol import org.session.libsignal.service.loki.utilities.* private typealias Path = List @@ -25,16 +26,21 @@ private typealias Path = List * See the "Onion Requests" section of [The Session Whitepaper](https://arxiv.org/pdf/2002.04609.pdf) for more information. */ object OnionRequestAPI { + private val database: LokiAPIDatabaseProtocol + get() = SnodeModule.shared.storage + private val broadcaster: Broadcaster + get() = SnodeModule.shared.broadcaster private val pathFailureCount = mutableMapOf() private val snodeFailureCount = mutableMapOf() + var guardSnodes = setOf() var paths: List // Not a set to ensure we consistently show the same path to the user - get() = SnodeAPI.database.getOnionRequestPaths() + get() = database.getOnionRequestPaths() set(newValue) { if (newValue.isEmpty()) { - SnodeAPI.database.clearOnionRequestPaths() + database.clearOnionRequestPaths() } else { - SnodeAPI.database.setOnionRequestPaths(newValue) + database.setOnionRequestPaths(newValue) } } @@ -51,16 +57,15 @@ object OnionRequestAPI { * The number of times a snode can fail before it's replaced. */ private const val snodeFailureThreshold = 1 - /** - * The number of paths to maintain. - */ - const val targetPathCount = 2 // A main path and a backup path for the case where the target snode is in the main path - /** * The number of guard snodes required to maintain `targetPathCount` paths. */ private val targetGuardSnodeCount get() = targetPathCount // One per path + /** + * The number of paths to maintain. + */ + const val targetPathCount = 2 // A main path and a backup path for the case where the target snode is in the main path // endregion class HTTPRequestFailedAtDestinationException(val statusCode: Int, val json: Map<*, *>) @@ -113,7 +118,7 @@ object OnionRequestAPI { return Promise.of(guardSnodes) } else { Log.d("Loki", "Populating guard snode cache.") - return SnodeAPI.getRandomSnode().bind(SnodeAPI.sharedContext) { // Just used to populate the snode pool + return SnodeAPI.getRandomSnode().bind { // Just used to populate the snode pool var unusedSnodes = SnodeAPI.snodePool.minus(reusableGuardSnodes) val reusableGuardSnodeCount = reusableGuardSnodes.count() if (unusedSnodes.count() < (targetGuardSnodeCount - reusableGuardSnodeCount)) { throw InsufficientSnodesException() } @@ -138,7 +143,7 @@ object OnionRequestAPI { return deferred.promise } val promises = (0 until (targetGuardSnodeCount - reusableGuardSnodeCount)).map { getGuardSnode() } - all(promises).map(SnodeAPI.sharedContext) { guardSnodes -> + all(promises).map { guardSnodes -> val guardSnodesAsSet = (guardSnodes + reusableGuardSnodes).toSet() OnionRequestAPI.guardSnodes = guardSnodesAsSet guardSnodesAsSet @@ -153,10 +158,10 @@ object OnionRequestAPI { */ private fun buildPaths(reusablePaths: List): Promise, Exception> { Log.d("Loki", "Building onion request paths.") - SnodeAPI.broadcaster.broadcast("buildingPaths") - return SnodeAPI.getRandomSnode().bind(SnodeAPI.sharedContext) { // Just used to populate the snode pool + broadcaster.broadcast("buildingPaths") + return SnodeAPI.getRandomSnode().bind { // Just used to populate the snode pool val reusableGuardSnodes = reusablePaths.map { it[0] } - getGuardSnodes(reusableGuardSnodes).map(SnodeAPI.sharedContext) { guardSnodes -> + getGuardSnodes(reusableGuardSnodes).map { guardSnodes -> var unusedSnodes = SnodeAPI.snodePool.minus(guardSnodes).minus(reusablePaths.flatten()) val reusableGuardSnodeCount = reusableGuardSnodes.count() val pathSnodeCount = (targetGuardSnodeCount - reusableGuardSnodeCount) * pathSize - (targetGuardSnodeCount - reusableGuardSnodeCount) @@ -173,7 +178,7 @@ object OnionRequestAPI { } }.map { paths -> OnionRequestAPI.paths = paths + reusablePaths - SnodeAPI.broadcaster.broadcast("pathsBuilt") + broadcaster.broadcast("pathsBuilt") paths } } @@ -207,12 +212,12 @@ object OnionRequestAPI { buildPaths(paths) // Re-build paths in the background return Promise.of(getPath(paths)) } else { - return buildPaths(paths).map(SnodeAPI.sharedContext) { newPaths -> + return buildPaths(paths).map { newPaths -> getPath(newPaths) } } } else { - return buildPaths(listOf()).map(SnodeAPI.sharedContext) { newPaths -> + return buildPaths(listOf()).map { newPaths -> getPath(newPaths) } } @@ -263,10 +268,10 @@ object OnionRequestAPI { is Destination.Snode -> destination.snode is Destination.Server -> null } - return getPath(snodeToExclude).bind(SnodeAPI.sharedContext) { path -> + return getPath(snodeToExclude).bind { path -> guardSnode = path.first() // Encrypt in reverse order, i.e. the destination first - OnionRequestEncryption.encryptPayloadForDestination(payload, destination).bind(SnodeAPI.sharedContext) { r -> + OnionRequestEncryption.encryptPayloadForDestination(payload, destination).bind { r -> destinationSymmetricKey = r.symmetricKey // Recursively encrypt the layers of the onion (again in reverse order) encryptionResult = r @@ -278,7 +283,7 @@ object OnionRequestAPI { } else { val lhs = Destination.Snode(path.last()) path = path.dropLast(1) - return OnionRequestEncryption.encryptHop(lhs, rhs, encryptionResult).bind(SnodeAPI.sharedContext) { r -> + return OnionRequestEncryption.encryptHop(lhs, rhs, encryptionResult).bind { r -> encryptionResult = r rhs = lhs addLayer() @@ -287,7 +292,7 @@ object OnionRequestAPI { } addLayer() } - }.map(SnodeAPI.sharedContext) { OnionBuildingResult(guardSnode, encryptionResult, destinationSymmetricKey) } + }.map { OnionBuildingResult(guardSnode, encryptionResult, destinationSymmetricKey) } } /** diff --git a/libsession/src/main/java/org/session/libsession/snode/Snode.kt b/libsession/src/main/java/org/session/libsession/snode/Snode.kt index b02582846c..2bb2429eca 100644 --- a/libsession/src/main/java/org/session/libsession/snode/Snode.kt +++ b/libsession/src/main/java/org/session/libsession/snode/Snode.kt @@ -1,17 +1,10 @@ package org.session.libsession.snode class Snode(val address: String, val port: Int, val publicKeySet: KeySet?) { - val ip: String get() = address.removePrefix("https://") internal enum class Method(val rawValue: String) { - /** - * Only supported by snode targets. - */ GetSwarm("get_snodes_for_pubkey"), - /** - * Only supported by snode targets. - */ GetMessages("retrieve"), SendMessage("store") } diff --git a/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt b/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt index 9f8d417ed3..0cfda8f2d8 100644 --- a/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt +++ b/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt @@ -19,12 +19,10 @@ import org.session.libsignal.utilities.logging.Log import java.security.SecureRandom object SnodeAPI { - val database: LokiAPIDatabaseProtocol - get() = SnodeConfiguration.shared.storage - val broadcaster: Broadcaster - get() = SnodeConfiguration.shared.broadcaster - val sharedContext = Kovenant.createContext() - val messagePollingContext = Kovenant.createContext() + private val database: LokiAPIDatabaseProtocol + get() = SnodeModule.shared.storage + private val broadcaster: Broadcaster + get() = SnodeModule.shared.broadcaster internal var snodeFailureCount: MutableMap = mutableMapOf() internal var snodePool: Set @@ -33,30 +31,27 @@ object SnodeAPI { // Settings private val maxRetryCount = 6 - private val minimumSnodePoolCount = 64 + private val minimumSnodePoolCount = 24 private val minimumSwarmSnodeCount = 2 - - // use port 4433 if API level can handle network security config and enforce pinned certificates - private val seedPort = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) 443 else 4433 + // Use port 4433 if the API level can handle the network security configuration and enforce pinned certificates + private val seedNodePort = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) 443 else 4433 private val seedNodePool by lazy { if (useTestnet) { setOf( "http://public.loki.foundation:38157" ) } else { - setOf( "https://storage.seed1.loki.network:$seedPort", "https://storage.seed3.loki.network:$seedPort", "https://public.loki.foundation:$seedPort" ) + setOf( "https://storage.seed1.loki.network:$seedNodePort", "https://storage.seed3.loki.network:$seedNodePort", "https://public.loki.foundation:$seedNodePort" ) } } private val snodeFailureThreshold = 4 private val targetSwarmSnodeCount = 2 private val useOnionRequests = true - internal val useTestnet = false - internal var powDifficulty = 1 + internal val useTestnet = true // Error internal sealed class Error(val description: String) : Exception(description) { object Generic : Error("An error occurred.") - object ClockOutOfSync : Error("The user's clock is out of sync with the service node network.") - object RandomSnodePoolUpdatingFailed : Error("Failed to update random service node pool.") + object ClockOutOfSync : Error("Your clock is out of sync with the Service Node network.") } // Internal API @@ -94,12 +89,12 @@ object SnodeAPI { val parameters = mapOf( "method" to "get_n_service_nodes", "params" to mapOf( - "active_only" to true, - "fields" to mapOf( "public_ip" to true, "storage_port" to true, "pubkey_x25519" to true, "pubkey_ed25519" to true ) + "active_only" to true, + "fields" to mapOf( "public_ip" to true, "storage_port" to true, "pubkey_x25519" to true, "pubkey_ed25519" to true ) ) ) val deferred = deferred() - deferred(SnodeAPI.sharedContext) + deferred() ThreadUtils.queue { try { val json = HTTP.execute(HTTP.Verb.POST, url, parameters, useSeedNodeConnection = true) @@ -170,7 +165,7 @@ object SnodeAPI { val parameters = mapOf( "pubKey" to if (useTestnet) publicKey.removing05PrefixIfNeeded() else publicKey ) return getRandomSnode().bind { invoke(Snode.Method.GetSwarm, it, publicKey, parameters) - }.map(sharedContext) { + }.map { parseSnodes(it).toSet() }.success { database.setSwarm(publicKey, it) @@ -186,8 +181,8 @@ object SnodeAPI { fun getMessages(publicKey: String): MessageListPromise { return retryIfNeeded(maxRetryCount) { - getSingleTargetSnode(publicKey).bind(messagePollingContext) { snode -> - getRawMessages(snode, publicKey).map(messagePollingContext) { parseRawMessagesResponse(it, snode, publicKey) } + getSingleTargetSnode(publicKey).bind { snode -> + getRawMessages(snode, publicKey).map { parseRawMessagesResponse(it, snode, publicKey) } } } } @@ -199,19 +194,7 @@ object SnodeAPI { swarm.map { snode -> val parameters = message.toJSON() retryIfNeeded(maxRetryCount) { - invoke(Snode.Method.SendMessage, snode, destination, parameters).map { rawResponse -> - val json = rawResponse as? Map<*, *> - val powDifficulty = json?.get("difficulty") as? Int - if (powDifficulty != null) { - if (powDifficulty != SnodeAPI.powDifficulty && powDifficulty < 100) { - Log.d("Loki", "Setting proof of work difficulty to $powDifficulty (snode: $snode).") - SnodeAPI.powDifficulty = powDifficulty - } - } else { - Log.d("Loki", "Failed to update proof of work difficulty from: ${rawResponse.prettifiedDescription()}.") - } - rawResponse - } + invoke(Snode.Method.SendMessage, snode, destination, parameters) } }.toSet() } @@ -256,7 +239,6 @@ object SnodeAPI { private fun updateLastMessageHashValueIfPossible(snode: Snode, publicKey: String, rawMessages: List<*>) { val lastMessageAsJSON = rawMessages.lastOrNull() as? Map<*, *> val hashValue = lastMessageAsJSON?.get("hash") as? String - val expiration = lastMessageAsJSON?.get("expiration") as? Int if (hashValue != null) { database.setLastMessageHashValue(snode, publicKey, hashValue) } else if (rawMessages.isNotEmpty()) { @@ -316,20 +298,6 @@ object SnodeAPI { Log.d("Loki", "Got a 421 without an associated public key.") } } - 432 -> { - // The PoW difficulty is too low - val powDifficulty = json?.get("difficulty") as? Int - if (powDifficulty != null) { - if (powDifficulty < 100) { - Log.d("Loki", "Setting proof of work difficulty to $powDifficulty (snode: $snode).") - SnodeAPI.powDifficulty = powDifficulty - } else { - handleBadSnode() - } - } else { - Log.d("Loki", "Failed to update proof of work difficulty.") - } - } else -> { handleBadSnode() Log.d("Loki", "Unhandled response code: ${statusCode}.") @@ -338,8 +306,6 @@ object SnodeAPI { } return null } - - } // Type Aliases diff --git a/libsession/src/main/java/org/session/libsession/snode/SnodeMessage.kt b/libsession/src/main/java/org/session/libsession/snode/SnodeMessage.kt index 0a653e400b..086644b456 100644 --- a/libsession/src/main/java/org/session/libsession/snode/SnodeMessage.kt +++ b/libsession/src/main/java/org/session/libsession/snode/SnodeMessage.kt @@ -12,12 +12,14 @@ data class SnodeMessage( // When the proof of work was calculated. val timestamp: Long ) { + internal fun toJSON(): Map { - return mutableMapOf( - "pubKey" to if (SnodeAPI.useTestnet) recipient.removing05PrefixIfNeeded() else recipient, - "data" to data, - "ttl" to ttl.toString(), - "timestamp" to timestamp.toString(), - "nonce" to "") + return mapOf( + "pubKey" to if (SnodeAPI.useTestnet) recipient.removing05PrefixIfNeeded() else recipient, + "data" to data, + "ttl" to ttl.toString(), + "timestamp" to timestamp.toString(), + "nonce" to "" + ) } } diff --git a/libsession/src/main/java/org/session/libsession/snode/SnodeConfiguration.kt b/libsession/src/main/java/org/session/libsession/snode/SnodeModule.kt similarity index 63% rename from libsession/src/main/java/org/session/libsession/snode/SnodeConfiguration.kt rename to libsession/src/main/java/org/session/libsession/snode/SnodeModule.kt index a5ff44e7ff..95613ffda2 100644 --- a/libsession/src/main/java/org/session/libsession/snode/SnodeConfiguration.kt +++ b/libsession/src/main/java/org/session/libsession/snode/SnodeModule.kt @@ -3,13 +3,14 @@ package org.session.libsession.snode import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol import org.session.libsignal.service.loki.utilities.Broadcaster -class SnodeConfiguration(val storage: LokiAPIDatabaseProtocol, val broadcaster: Broadcaster) { +class SnodeModule(val storage: LokiAPIDatabaseProtocol, val broadcaster: Broadcaster) { + companion object { - lateinit var shared: SnodeConfiguration + lateinit var shared: SnodeModule fun configure(storage: LokiAPIDatabaseProtocol, broadcaster: Broadcaster) { if (Companion::shared.isInitialized) { return } - shared = SnodeConfiguration(storage, broadcaster) + shared = SnodeModule(storage, broadcaster) } } } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/snode/StorageProtocol.kt b/libsession/src/main/java/org/session/libsession/snode/StorageProtocol.kt index ec79d1ccaf..85ab507114 100644 --- a/libsession/src/main/java/org/session/libsession/snode/StorageProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/snode/StorageProtocol.kt @@ -1,6 +1,7 @@ package org.session.libsession.snode interface SnodeStorageProtocol { + fun getSnodePool(): Set fun setSnodePool(newValue: Set) fun getOnionRequestPaths(): List> From 676c307412f70444fbfdcda9a40bb42c5b546669 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Mon, 26 Apr 2021 10:58:48 +1000 Subject: [PATCH 04/13] Clean --- .../database/MessageDataProvider.kt | 1 - .../messaging/avatars/AvatarHelper.java | 1 - .../messaging/avatars/ContactPhoto.java | 2 -- .../avatars/FallbackContactPhoto.java | 1 - .../avatars/GeneratedContactPhoto.java | 1 - .../avatars/GroupRecordContactPhoto.java | 1 - .../avatars/ProfileContactPhoto.java | 1 - .../messaging/avatars/SystemContactPhoto.java | 1 - .../messaging/jobs/AttachmentDownloadJob.kt | 20 ++++------- .../messaging/jobs/AttachmentUploadJob.kt | 34 ++++++------------- .../libsession/messaging/jobs/Data.java | 1 - .../session/libsession/messaging/jobs/Job.kt | 4 +-- .../libsession/messaging/jobs/JobDelegate.kt | 1 + .../libsession/messaging/jobs/JobQueue.kt | 10 +++--- .../messaging/jobs/MessageReceiveJob.kt | 6 ++-- .../messaging/jobs/MessageSendJob.kt | 12 +++---- .../messaging/jobs/NotifyPNServerJob.kt | 10 ++---- .../messaging/jobs/SessionJobInstantiator.kt | 2 -- .../jobs/SessionJobManagerFactories.kt | 2 -- .../control/ClosedGroupControlMessage.kt | 34 ++----------------- .../messaging/utilities/DotNetAPI.kt | 10 +++--- .../utilities/LinkedBlockingLifoQueue.java | 1 - .../libsession/utilities/NumberUtil.kt | 1 - .../libsession/utilities/SSKEnvironment.kt | 1 + .../concurrent/AssertedSuccessListener.java | 1 + .../DynamicLanguageContextWrapper.java | 1 - .../dynamiclanguage/LanguageString.java | 3 +- .../utilities/preferences/ProfileKeyUtil.java | 1 - .../utilities/task/SnackbarAsyncTask.java | 1 - .../libsession/utilities/views/Stub.java | 1 - 30 files changed, 44 insertions(+), 122 deletions(-) diff --git a/libsession/src/main/java/org/session/libsession/database/MessageDataProvider.kt b/libsession/src/main/java/org/session/libsession/database/MessageDataProvider.kt index d3065e5772..f28001cc7c 100644 --- a/libsession/src/main/java/org/session/libsession/database/MessageDataProvider.kt +++ b/libsession/src/main/java/org/session/libsession/database/MessageDataProvider.kt @@ -30,7 +30,6 @@ interface MessageDataProvider { fun updateAttachmentAfterUploadSucceeded(attachmentId: Long, attachmentStream: SignalServiceAttachmentStream, attachmentKey: ByteArray, uploadResult: DotNetAPI.UploadResult) fun updateAttachmentAfterUploadFailed(attachmentId: Long) - // Quotes fun getMessageForQuote(timestamp: Long, author: Address): Pair? fun getAttachmentsAndLinkPreviewFor(mmsId: Long): List fun getMessageBodyFor(timestamp: Long, author: String): String diff --git a/libsession/src/main/java/org/session/libsession/messaging/avatars/AvatarHelper.java b/libsession/src/main/java/org/session/libsession/messaging/avatars/AvatarHelper.java index b5286cd1ca..aad0051bbf 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/avatars/AvatarHelper.java +++ b/libsession/src/main/java/org/session/libsession/messaging/avatars/AvatarHelper.java @@ -1,6 +1,5 @@ package org.session.libsession.messaging.avatars; - import android.content.Context; import androidx.annotation.NonNull; diff --git a/libsession/src/main/java/org/session/libsession/messaging/avatars/ContactPhoto.java b/libsession/src/main/java/org/session/libsession/messaging/avatars/ContactPhoto.java index 93bc7957a6..e11eb5f36c 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/avatars/ContactPhoto.java +++ b/libsession/src/main/java/org/session/libsession/messaging/avatars/ContactPhoto.java @@ -1,6 +1,5 @@ package org.session.libsession.messaging.avatars; - import android.content.Context; import android.net.Uri; @@ -19,5 +18,4 @@ public interface ContactPhoto extends Key { @Nullable Uri getUri(@NonNull Context context); boolean isProfilePhoto(); - } diff --git a/libsession/src/main/java/org/session/libsession/messaging/avatars/FallbackContactPhoto.java b/libsession/src/main/java/org/session/libsession/messaging/avatars/FallbackContactPhoto.java index 388266b6c8..c21c0438bd 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/avatars/FallbackContactPhoto.java +++ b/libsession/src/main/java/org/session/libsession/messaging/avatars/FallbackContactPhoto.java @@ -7,5 +7,4 @@ public interface FallbackContactPhoto { public Drawable asDrawable(Context context, int color); public Drawable asDrawable(Context context, int color, boolean inverted); - } diff --git a/libsession/src/main/java/org/session/libsession/messaging/avatars/GeneratedContactPhoto.java b/libsession/src/main/java/org/session/libsession/messaging/avatars/GeneratedContactPhoto.java index 6066db0321..d3be9cfbf3 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/avatars/GeneratedContactPhoto.java +++ b/libsession/src/main/java/org/session/libsession/messaging/avatars/GeneratedContactPhoto.java @@ -19,7 +19,6 @@ import org.session.libsession.utilities.ViewUtil; import java.util.regex.Pattern; - public class GeneratedContactPhoto implements FallbackContactPhoto { private static final Pattern PATTERN = Pattern.compile("[^\\p{L}\\p{Nd}\\p{S}]+"); diff --git a/libsession/src/main/java/org/session/libsession/messaging/avatars/GroupRecordContactPhoto.java b/libsession/src/main/java/org/session/libsession/messaging/avatars/GroupRecordContactPhoto.java index 818b6df3c6..24c2dfec93 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/avatars/GroupRecordContactPhoto.java +++ b/libsession/src/main/java/org/session/libsession/messaging/avatars/GroupRecordContactPhoto.java @@ -1,6 +1,5 @@ package org.session.libsession.messaging.avatars; - import android.content.Context; import android.net.Uri; diff --git a/libsession/src/main/java/org/session/libsession/messaging/avatars/ProfileContactPhoto.java b/libsession/src/main/java/org/session/libsession/messaging/avatars/ProfileContactPhoto.java index 164f4dd747..19109b86ad 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/avatars/ProfileContactPhoto.java +++ b/libsession/src/main/java/org/session/libsession/messaging/avatars/ProfileContactPhoto.java @@ -1,6 +1,5 @@ package org.session.libsession.messaging.avatars; - import android.content.Context; import android.net.Uri; diff --git a/libsession/src/main/java/org/session/libsession/messaging/avatars/SystemContactPhoto.java b/libsession/src/main/java/org/session/libsession/messaging/avatars/SystemContactPhoto.java index b9395b75d6..002a61de98 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/avatars/SystemContactPhoto.java +++ b/libsession/src/main/java/org/session/libsession/messaging/avatars/SystemContactPhoto.java @@ -1,6 +1,5 @@ package org.session.libsession.messaging.avatars; - import android.content.Context; import android.net.Uri; diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt index 1a0b9f9ef3..a1e3077de7 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt @@ -11,13 +11,10 @@ import java.io.File import java.io.FileInputStream class AttachmentDownloadJob(val attachmentID: Long, val databaseMessageID: Long): Job { - override var delegate: JobDelegate? = null override var id: String? = null override var failureCount: Int = 0 - private val MAX_ATTACHMENT_SIZE = 10 * 1024 * 1024 - // Error internal sealed class Error(val description: String) : Exception(description) { object NoAttachment : Error("No such attachment.") @@ -28,17 +25,17 @@ class AttachmentDownloadJob(val attachmentID: Long, val databaseMessageID: Long) companion object { val KEY: String = "AttachmentDownloadJob" - //keys used for database storage purpose + // Keys used for database storage private val KEY_ATTACHMENT_ID = "attachment_id" private val KEY_TS_INCOMING_MESSAGE_ID = "tsIncoming_message_id" } override fun execute() { val handleFailure: (java.lang.Exception) -> Unit = { exception -> - if(exception is Error && exception == Error.NoAttachment) { + if (exception == Error.NoAttachment) { MessagingConfiguration.shared.messageDataProvider.setAttachmentState(AttachmentState.FAILED, attachmentID, databaseMessageID) this.handlePermanentFailure(exception) - } else if (exception is DotNetAPI.Error && exception == DotNetAPI.Error.ParsingFailed) { + } else if (exception == DotNetAPI.Error.ParsingFailed) { // No need to retry if the response is invalid. Most likely this means we (incorrectly) // got a "Cannot GET ..." error from the file server. MessagingConfiguration.shared.messageDataProvider.setAttachmentState(AttachmentState.FAILED, attachmentID, databaseMessageID) @@ -53,9 +50,7 @@ class AttachmentDownloadJob(val attachmentID: Long, val databaseMessageID: Long) messageDataProvider.setAttachmentState(AttachmentState.STARTED, attachmentID, this.databaseMessageID) val tempFile = createTempFile() - FileServerAPI.shared.downloadFile(tempFile, attachment.url, MAX_ATTACHMENT_SIZE, null) - - // DECRYPTION + FileServerAPI.shared.downloadFile(tempFile, attachment.url, null) // Assume we're retrieving an attachment for an open group server if the digest is not set val stream = if (attachment.digest?.size ?: 0 == 0 || attachment.key.isNullOrEmpty()) FileInputStream(tempFile) @@ -89,12 +84,10 @@ class AttachmentDownloadJob(val attachmentID: Long, val databaseMessageID: Long) return file } - //database functions - override fun serialize(): Data { return Data.Builder().putLong(KEY_ATTACHMENT_ID, attachmentID) - .putLong(KEY_TS_INCOMING_MESSAGE_ID, databaseMessageID) - .build(); + .putLong(KEY_TS_INCOMING_MESSAGE_ID, databaseMessageID) + .build(); } override fun getFactoryKey(): String { @@ -102,6 +95,7 @@ class AttachmentDownloadJob(val attachmentID: Long, val databaseMessageID: Long) } class Factory: Job.Factory { + override fun create(data: Data): AttachmentDownloadJob { return AttachmentDownloadJob(data.getLong(KEY_ATTACHMENT_ID), data.getLong(KEY_TS_INCOMING_MESSAGE_ID)) } diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentUploadJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentUploadJob.kt index 03c06e6f63..f05a3bcf81 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentUploadJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentUploadJob.kt @@ -18,7 +18,6 @@ import org.session.libsignal.service.loki.utilities.PlaintextOutputStreamFactory import org.session.libsignal.utilities.logging.Log class AttachmentUploadJob(val attachmentID: Long, val threadID: String, val message: Message, val messageSendJobID: String) : Job { - override var delegate: JobDelegate? = null override var id: String? = null override var failureCount: Int = 0 @@ -34,9 +33,7 @@ class AttachmentUploadJob(val attachmentID: Long, val threadID: String, val mess val TAG = AttachmentUploadJob::class.simpleName val KEY: String = "AttachmentUploadJob" - val maxFailureCount: Int = 20 - - //keys used for database storage purpose + // Keys used for database storage private val KEY_ATTACHMENT_ID = "attachment_id" private val KEY_THREAD_ID = "thread_id" private val KEY_MESSAGE = "message" @@ -46,16 +43,12 @@ class AttachmentUploadJob(val attachmentID: Long, val threadID: String, val mess override fun execute() { try { val attachment = MessagingConfiguration.shared.messageDataProvider.getScaledSignalAttachmentStream(attachmentID) - ?: return handleFailure(Error.NoAttachment) + ?: return handleFailure(Error.NoAttachment) - var server = FileServerAPI.shared.server - var shouldEncrypt = true val usePadding = false val openGroup = MessagingConfiguration.shared.storage.getOpenGroup(threadID) - openGroup?.let { - server = it.server - shouldEncrypt = false - } + val server = if (openGroup != null) openGroup.server else FileServerAPI.shared.server + val shouldEncrypt = (openGroup == null) // Encrypt if this isn't an open group val attachmentKey = Util.getSecretBytes(64) val paddedLength = if (usePadding) PaddingInputStream.getPaddedSize(attachment.length) else attachment.length @@ -67,9 +60,8 @@ class AttachmentUploadJob(val attachmentID: Long, val threadID: String, val mess val uploadResult = FileServerAPI.shared.uploadAttachment(server, attachmentData) handleSuccess(attachment, attachmentKey, uploadResult) - } catch (e: java.lang.Exception) { - if (e is Error && e == Error.NoAttachment) { + if (e == Error.NoAttachment) { this.handlePermanentFailure(e) } else if (e is DotNetAPI.Error && !e.isRetryable) { this.handlePermanentFailure(e) @@ -77,7 +69,6 @@ class AttachmentUploadJob(val attachmentID: Long, val threadID: String, val mess this.handleFailure(e) } } - } private fun handleSuccess(attachment: SignalServiceAttachmentStream, attachmentKey: ByteArray, uploadResult: DotNetAPI.UploadResult) { @@ -97,7 +88,7 @@ class AttachmentUploadJob(val attachmentID: Long, val threadID: String, val mess private fun handleFailure(e: Exception) { Log.w(TAG, "Attachment upload failed due to error: $this.") delegate?.handleJobFailed(this, e) - if (failureCount + 1 == AttachmentUploadJob.maxFailureCount) { + if (failureCount + 1 == maxFailureCount) { failAssociatedMessageSendJob(e) } } @@ -111,10 +102,7 @@ class AttachmentUploadJob(val attachmentID: Long, val threadID: String, val mess } } - //database functions - override fun serialize(): Data { - //serialize Message property val kryo = Kryo() kryo.isRegistrationRequired = false val serializedMessage = ByteArray(4096) @@ -122,10 +110,10 @@ class AttachmentUploadJob(val attachmentID: Long, val threadID: String, val mess kryo.writeObject(output, message) output.close() return Data.Builder().putLong(KEY_ATTACHMENT_ID, attachmentID) - .putString(KEY_THREAD_ID, threadID) - .putByteArray(KEY_MESSAGE, serializedMessage) - .putString(KEY_MESSAGE_SEND_JOB_ID, messageSendJobID) - .build(); + .putString(KEY_THREAD_ID, threadID) + .putByteArray(KEY_MESSAGE, serializedMessage) + .putString(KEY_MESSAGE_SEND_JOB_ID, messageSendJobID) + .build(); } override fun getFactoryKey(): String { @@ -133,9 +121,9 @@ class AttachmentUploadJob(val attachmentID: Long, val threadID: String, val mess } class Factory: Job.Factory { + override fun create(data: Data): AttachmentUploadJob { val serializedMessage = data.getByteArray(KEY_MESSAGE) - //deserialize Message property val kryo = Kryo() val input = Input(serializedMessage) val message: Message = kryo.readObject(input, Message::class.java) diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/Data.java b/libsession/src/main/java/org/session/libsession/messaging/jobs/Data.java index 67c142ab3c..310cfed336 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/Data.java +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/Data.java @@ -12,7 +12,6 @@ import org.session.libsession.utilities.ParcelableUtil; import java.util.HashMap; import java.util.Map; -// TODO AC: For now parcelable objects utilize byteArrays field to store their data into. // Introduce a dedicated Map field specifically for parcelable needs. public class Data { diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/Job.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/Job.kt index 101a253b88..4693fddf4a 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/Job.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/Job.kt @@ -8,15 +8,13 @@ interface Job { val maxFailureCount: Int companion object { - //keys used for database storage purpose + // Keys used for database storage private val KEY_ID = "id" private val KEY_FAILURE_COUNT = "failure_count" } fun execute() - //database functions - fun serialize(): Data /** diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/JobDelegate.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/JobDelegate.kt index 0efe78fbda..535ea27f3c 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/JobDelegate.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/JobDelegate.kt @@ -1,6 +1,7 @@ package org.session.libsession.messaging.jobs interface JobDelegate { + fun handleJobSucceeded(job: Job) fun handleJobFailed(job: Job, error: Exception) fun handleJobFailedPermanently(job: Job, error: Exception) diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/JobQueue.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/JobQueue.kt index d56bdfd9b7..9e8e1374dc 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/JobQueue.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/JobQueue.kt @@ -14,19 +14,17 @@ import kotlin.math.min import kotlin.math.pow import kotlin.math.roundToLong - class JobQueue : JobDelegate { private var hasResumedPendingJobs = false // Just for debugging - private val jobTimestampMap = ConcurrentHashMap() - private val dispatcher = Executors.newSingleThreadExecutor().asCoroutineDispatcher() private val scope = GlobalScope + SupervisorJob() private val queue = Channel(UNLIMITED) + val timer = Timer() init { - // process jobs + // Process jobs scope.launch(dispatcher) { while (isActive) { queue.receive().let { job -> @@ -49,7 +47,7 @@ class JobQueue : JobDelegate { private fun addWithoutExecuting(job: Job) { // When adding multiple jobs in rapid succession, timestamps might not be good enough as a unique ID. To - // deal with this we keep track of the number of jobs with a given timestamp and that to the end of the + // deal with this we keep track of the number of jobs with a given timestamp and add that to the end of the // timestamp to make it a unique ID. We can't use a random number because we do still want to keep track // of the order in which the jobs were added. val currentTime = System.currentTimeMillis() @@ -70,7 +68,7 @@ class JobQueue : JobDelegate { val allPendingJobs = MessagingConfiguration.shared.storage.getAllPendingJobs(type) allPendingJobs.sortedBy { it.id }.forEach { job -> Log.i("Jobs", "Resuming pending job of type: ${job::class.simpleName}.") - queue.offer(job) // offer always called on unlimited capacity + queue.offer(job) // Offer always called on unlimited capacity } } } diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageReceiveJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageReceiveJob.kt index 143394312f..7c527bebbf 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageReceiveJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageReceiveJob.kt @@ -7,7 +7,6 @@ import org.session.libsession.messaging.sending_receiving.handle import org.session.libsignal.utilities.logging.Log class MessageReceiveJob(val data: ByteArray, val isBackgroundPoll: Boolean, val openGroupMessageServerID: Long? = null, val openGroupID: String? = null) : Job { - override var delegate: JobDelegate? = null override var id: String? = null override var failureCount: Int = 0 @@ -20,7 +19,7 @@ class MessageReceiveJob(val data: ByteArray, val isBackgroundPoll: Boolean, val private val RECEIVE_LOCK = Object() - //keys used for database storage purpose + // Keys used for database storage private val KEY_DATA = "data" private val KEY_IS_BACKGROUND_POLL = "is_background_poll" private val KEY_OPEN_GROUP_MESSAGE_SERVER_ID = "openGroupMessageServerID" @@ -68,8 +67,6 @@ class MessageReceiveJob(val data: ByteArray, val isBackgroundPoll: Boolean, val delegate?.handleJobFailed(this, e) } - //database functions - override fun serialize(): Data { val builder = Data.Builder().putByteArray(KEY_DATA, data) .putBoolean(KEY_IS_BACKGROUND_POLL, isBackgroundPoll) @@ -83,6 +80,7 @@ class MessageReceiveJob(val data: ByteArray, val isBackgroundPoll: Boolean, val } class Factory: Job.Factory { + override fun create(data: Data): MessageReceiveJob { return MessageReceiveJob(data.getByteArray(KEY_DATA), data.getBoolean(KEY_IS_BACKGROUND_POLL), data.getLong(KEY_OPEN_GROUP_MESSAGE_SERVER_ID), data.getString(KEY_OPEN_GROUP_ID)) } diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageSendJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageSendJob.kt index 1a630b55ae..066ab85b2e 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageSendJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageSendJob.kt @@ -11,7 +11,6 @@ import org.session.libsession.messaging.sending_receiving.MessageSender import org.session.libsignal.utilities.logging.Log class MessageSendJob(val message: Message, val destination: Destination) : Job { - override var delegate: JobDelegate? = null override var id: String? = null override var failureCount: Int = 0 @@ -22,7 +21,7 @@ class MessageSendJob(val message: Message, val destination: Destination) : Job { val TAG = MessageSendJob::class.simpleName val KEY: String = "MessageSendJob" - //keys used for database storage purpose + // Keys used for database storage private val KEY_MESSAGE = "message" private val KEY_DESTINATION = "destination" } @@ -77,10 +76,7 @@ class MessageSendJob(val message: Message, val destination: Destination) : Job { delegate?.handleJobFailed(this, error) } - //database functions - override fun serialize(): Data { - //serialize Message and Destination properties val kryo = Kryo() kryo.isRegistrationRequired = false val output = Output(ByteArray(4096), -1) // maxBufferSize '-1' will dynamically grow internally if we run out of room serializing the message @@ -92,8 +88,8 @@ class MessageSendJob(val message: Message, val destination: Destination) : Job { output.close() val serializedDestination = output.toBytes() return Data.Builder().putByteArray(KEY_MESSAGE, serializedMessage) - .putByteArray(KEY_DESTINATION, serializedDestination) - .build(); + .putByteArray(KEY_DESTINATION, serializedDestination) + .build(); } override fun getFactoryKey(): String { @@ -101,10 +97,10 @@ class MessageSendJob(val message: Message, val destination: Destination) : Job { } class Factory: Job.Factory { + override fun create(data: Data): MessageSendJob { val serializedMessage = data.getByteArray(KEY_MESSAGE) val serializedDestination = data.getByteArray(KEY_DESTINATION) - //deserialize Message and Destination properties val kryo = Kryo() var input = Input(serializedMessage) val message = kryo.readClassAndObject(input) as Message diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/NotifyPNServerJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/NotifyPNServerJob.kt index f78425d6e1..fb99f54f56 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/NotifyPNServerJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/NotifyPNServerJob.kt @@ -26,7 +26,7 @@ class NotifyPNServerJob(val message: SnodeMessage) : Job { companion object { val KEY: String = "NotifyPNServerJob" - //keys used for database storage purpose + // Keys used for database storage private val KEY_MESSAGE = "message" } @@ -61,18 +61,14 @@ class NotifyPNServerJob(val message: SnodeMessage) : Job { delegate?.handleJobFailed(this, error) } - //database functions - override fun serialize(): Data { - //serialize SnodeMessage property val kryo = Kryo() kryo.isRegistrationRequired = false val serializedMessage = ByteArray(4096) val output = Output(serializedMessage) kryo.writeObject(output, message) output.close() - return Data.Builder().putByteArray(KEY_MESSAGE, serializedMessage) - .build(); + return Data.Builder().putByteArray(KEY_MESSAGE, serializedMessage).build(); } override fun getFactoryKey(): String { @@ -80,9 +76,9 @@ class NotifyPNServerJob(val message: SnodeMessage) : Job { } class Factory: Job.Factory { + override fun create(data: Data): NotifyPNServerJob { val serializedMessage = data.getByteArray(KEY_MESSAGE) - //deserialize SnodeMessage property val kryo = Kryo() val input = Input(serializedMessage) val message: SnodeMessage = kryo.readObject(input, SnodeMessage::class.java) diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/SessionJobInstantiator.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/SessionJobInstantiator.kt index ca4be31fdd..bf0a1b2f8a 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/SessionJobInstantiator.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/SessionJobInstantiator.kt @@ -1,7 +1,5 @@ package org.session.libsession.messaging.jobs -import java.util.* - class SessionJobInstantiator(private val jobFactories: Map>) { fun instantiate(jobFactoryKey: String, data: Data): Job { diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/SessionJobManagerFactories.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/SessionJobManagerFactories.kt index 6ca99c298a..e7c02361e1 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/SessionJobManagerFactories.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/SessionJobManagerFactories.kt @@ -1,7 +1,5 @@ package org.session.libsession.messaging.jobs -import java.util.* - class SessionJobManagerFactories { companion object { diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupControlMessage.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupControlMessage.kt index fa6544fc2a..83c223b1ac 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupControlMessage.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupControlMessage.kt @@ -28,15 +28,10 @@ class ClosedGroupControlMessage() : ControlMessage() { var kind: Kind? = null - // Kind enum sealed class Kind { class New(var publicKey: ByteString, var name: String, var encryptionKeyPair: ECKeyPair?, var members: List, var admins: List) : Kind() { internal constructor(): this(ByteString.EMPTY, "", null, listOf(), listOf()) } - /// - Note: Deprecated in favor of more explicit group updates. - class Update(var name: String, var members: List) : Kind() { - internal constructor(): this("", listOf()) - } /// An encryption key pair encrypted for each member individually. /// /// - Note: `publicKey` is only set when an encryption key pair is sent in a one-to-one context (i.e. not in a group). @@ -53,18 +48,15 @@ class ClosedGroupControlMessage() : ControlMessage() { internal constructor(): this(listOf()) } class MemberLeft() : Kind() - class EncryptionKeyPairRequest(): Kind() val description: String = when(this) { is New -> "new" - is Update -> "update" is EncryptionKeyPair -> "encryptionKeyPair" is NameChange -> "nameChange" is MembersAdded -> "membersAdded" is MembersRemoved -> "membersRemoved" is MemberLeft -> "memberLeft" - is EncryptionKeyPairRequest -> "encryptionKeyPairRequest" } } @@ -75,12 +67,11 @@ class ClosedGroupControlMessage() : ControlMessage() { if (!proto.hasDataMessage() || !proto.dataMessage.hasClosedGroupControlMessage()) return null val closedGroupControlMessageProto = proto.dataMessage?.closedGroupControlMessage!! val kind: Kind - when(closedGroupControlMessageProto.type) { + when (closedGroupControlMessageProto.type) { DataMessage.ClosedGroupControlMessage.Type.NEW -> { val publicKey = closedGroupControlMessageProto.publicKey ?: return null val name = closedGroupControlMessageProto.name ?: return null val encryptionKeyPairAsProto = closedGroupControlMessageProto.encryptionKeyPair ?: return null - try { val encryptionKeyPair = ECKeyPair(DjbECPublicKey(encryptionKeyPairAsProto.publicKey.toByteArray()), DjbECPrivateKey(encryptionKeyPairAsProto.privateKey.toByteArray())) kind = Kind.New(publicKey, name, encryptionKeyPair, closedGroupControlMessageProto.membersList, closedGroupControlMessageProto.adminsList) @@ -89,10 +80,6 @@ class ClosedGroupControlMessage() : ControlMessage() { return null } } - DataMessage.ClosedGroupControlMessage.Type.UPDATE -> { - val name = closedGroupControlMessageProto.name ?: return null - kind = Kind.Update(name, closedGroupControlMessageProto.membersList) - } DataMessage.ClosedGroupControlMessage.Type.ENCRYPTION_KEY_PAIR -> { val publicKey = closedGroupControlMessageProto.publicKey val wrappers = closedGroupControlMessageProto.wrappersList.mapNotNull { KeyPairWrapper.fromProto(it) } @@ -111,35 +98,28 @@ class ClosedGroupControlMessage() : ControlMessage() { DataMessage.ClosedGroupControlMessage.Type.MEMBER_LEFT -> { kind = Kind.MemberLeft() } - DataMessage.ClosedGroupControlMessage.Type.ENCRYPTION_KEY_PAIR_REQUEST -> { - kind = Kind.EncryptionKeyPairRequest() - } } return ClosedGroupControlMessage(kind) } } - // constructor internal constructor(kind: Kind?) : this() { this.kind = kind } - // validation override fun isValid(): Boolean { if (!super.isValid()) return false val kind = kind ?: return false return when(kind) { is Kind.New -> { !kind.publicKey.isEmpty && kind.name.isNotEmpty() && kind.encryptionKeyPair!!.publicKey != null - && kind.encryptionKeyPair!!.privateKey != null && kind.members.isNotEmpty() && kind.admins.isNotEmpty() + && kind.encryptionKeyPair!!.privateKey != null && kind.members.isNotEmpty() && kind.admins.isNotEmpty() } - is Kind.Update -> kind.name.isNotEmpty() is Kind.EncryptionKeyPair -> true is Kind.NameChange -> kind.name.isNotEmpty() is Kind.MembersAdded -> kind.members.isNotEmpty() is Kind.MembersRemoved -> kind.members.isNotEmpty() is Kind.MemberLeft -> true - is Kind.EncryptionKeyPairRequest -> true } } @@ -163,11 +143,6 @@ class ClosedGroupControlMessage() : ControlMessage() { closedGroupControlMessage.addAllMembers(kind.members) closedGroupControlMessage.addAllAdmins(kind.admins) } - is Kind.Update -> { - closedGroupControlMessage.type = DataMessage.ClosedGroupControlMessage.Type.UPDATE - closedGroupControlMessage.name = kind.name - closedGroupControlMessage.addAllMembers(kind.members) - } is Kind.EncryptionKeyPair -> { closedGroupControlMessage.type = DataMessage.ClosedGroupControlMessage.Type.ENCRYPTION_KEY_PAIR closedGroupControlMessage.publicKey = kind.publicKey @@ -188,9 +163,6 @@ class ClosedGroupControlMessage() : ControlMessage() { is Kind.MemberLeft -> { closedGroupControlMessage.type = DataMessage.ClosedGroupControlMessage.Type.MEMBER_LEFT } - is Kind.EncryptionKeyPairRequest -> { - // TODO: closedGroupControlMessage.type = SignalServiceProtos.ClosedGroupUpdateV2.Type.ENCRYPTION_KEY_PAIR_REQUEST - } } val contentProto = SignalServiceProtos.Content.newBuilder() val dataMessageProto = DataMessage.newBuilder() @@ -199,7 +171,7 @@ class ClosedGroupControlMessage() : ControlMessage() { setGroupContext(dataMessageProto) // Expiration timer // TODO: We * want * expiration timer updates to be explicit. But currently Android will disable the expiration timer for a conversation - // if it receives a message without the current expiration timer value attached to it... + // if it receives a message without the current expiration timer value attached to it... dataMessageProto.expireTimer = Recipient.from(MessagingConfiguration.shared.context, Address.fromSerialized(GroupUtil.doubleEncodeGroupID(recipient!!)), false).expireMessages contentProto.dataMessage = dataMessageProto.build() return contentProto.build() diff --git a/libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt b/libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt index 7d0af36477..d18527bfe5 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt @@ -185,14 +185,14 @@ open class DotNetAPI { /** * Blocks the calling thread. */ - fun downloadFile(destination: File, url: String, maxSize: Int, listener: SignalServiceAttachment.ProgressListener?) { + fun downloadFile(destination: File, url: String, listener: SignalServiceAttachment.ProgressListener?) { val outputStream = FileOutputStream(destination) // Throws var remainingAttempts = 4 var exception: Exception? = null while (remainingAttempts > 0) { remainingAttempts -= 1 try { - downloadFile(outputStream, url, maxSize, listener) + downloadFile(outputStream, url, listener) exception = null break } catch (e: Exception) { @@ -205,7 +205,7 @@ open class DotNetAPI { /** * Blocks the calling thread. */ - fun downloadFile(outputStream: OutputStream, url: String, maxSize: Int, listener: SignalServiceAttachment.ProgressListener?) { + fun downloadFile(outputStream: OutputStream, url: String, listener: SignalServiceAttachment.ProgressListener?) { // We need to throw a PushNetworkException or NonSuccessfulResponseCodeException // because the underlying Signal logic requires these to work correctly val oldPrefixedHost = "https://" + HttpUrl.get(url).host() @@ -228,7 +228,7 @@ open class DotNetAPI { throw PushNetworkException("Missing response body.") } val body = Base64.decode(result) - if (body.size > maxSize) { + if (body.size > FileServerAPI.maxFileSize) { Log.d("Loki", "Attachment size limit exceeded.") throw PushNetworkException("Max response size exceeded.") } @@ -239,7 +239,7 @@ open class DotNetAPI { while (bytes >= 0) { outputStream.write(buffer, 0, bytes) count += bytes - if (count > maxSize) { + if (count > FileServerAPI.maxFileSize) { Log.d("Loki", "Attachment size limit exceeded.") throw PushNetworkException("Max response size exceeded.") } diff --git a/libsession/src/main/java/org/session/libsession/utilities/LinkedBlockingLifoQueue.java b/libsession/src/main/java/org/session/libsession/utilities/LinkedBlockingLifoQueue.java index 053b7d4933..993f8334fb 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/LinkedBlockingLifoQueue.java +++ b/libsession/src/main/java/org/session/libsession/utilities/LinkedBlockingLifoQueue.java @@ -1,6 +1,5 @@ package org.session.libsession.utilities; - import java.util.concurrent.LinkedBlockingDeque; public class LinkedBlockingLifoQueue extends LinkedBlockingDeque { diff --git a/libsession/src/main/java/org/session/libsession/utilities/NumberUtil.kt b/libsession/src/main/java/org/session/libsession/utilities/NumberUtil.kt index 61ed56d0fd..6a2b969479 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/NumberUtil.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/NumberUtil.kt @@ -3,7 +3,6 @@ package org.session.libsession.utilities import android.telephony.PhoneNumberUtils import android.util.Patterns - object NumberUtil { private val emailPattern = Patterns.EMAIL_ADDRESS diff --git a/libsession/src/main/java/org/session/libsession/utilities/SSKEnvironment.kt b/libsession/src/main/java/org/session/libsession/utilities/SSKEnvironment.kt index 081300bc96..2e2bf37de4 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/SSKEnvironment.kt +++ b/libsession/src/main/java/org/session/libsession/utilities/SSKEnvironment.kt @@ -14,6 +14,7 @@ class SSKEnvironment( val notificationManager: MessageNotifier, val messageExpirationManager: MessageExpirationManagerProtocol ) { + interface TypingIndicatorsProtocol { fun didReceiveTypingStartedMessage(context: Context, threadId: Long, author: Address, device: Int) fun didReceiveTypingStoppedMessage(context: Context, threadId: Long, author: Address, device: Int, isReplacedByIncomingMessage: Boolean) diff --git a/libsession/src/main/java/org/session/libsession/utilities/concurrent/AssertedSuccessListener.java b/libsession/src/main/java/org/session/libsession/utilities/concurrent/AssertedSuccessListener.java index bda2ecc474..a23a81c412 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/concurrent/AssertedSuccessListener.java +++ b/libsession/src/main/java/org/session/libsession/utilities/concurrent/AssertedSuccessListener.java @@ -5,6 +5,7 @@ import org.session.libsignal.utilities.concurrent.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/libsession/src/main/java/org/session/libsession/utilities/dynamiclanguage/DynamicLanguageContextWrapper.java b/libsession/src/main/java/org/session/libsession/utilities/dynamiclanguage/DynamicLanguageContextWrapper.java index 8350ee4f5f..4c8193bb82 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/dynamiclanguage/DynamicLanguageContextWrapper.java +++ b/libsession/src/main/java/org/session/libsession/utilities/dynamiclanguage/DynamicLanguageContextWrapper.java @@ -30,5 +30,4 @@ public final class DynamicLanguageContextWrapper { copy.setLocale(locale); return copy; } - } diff --git a/libsession/src/main/java/org/session/libsession/utilities/dynamiclanguage/LanguageString.java b/libsession/src/main/java/org/session/libsession/utilities/dynamiclanguage/LanguageString.java index 86860c4a42..7db4244fb7 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/dynamiclanguage/LanguageString.java +++ b/libsession/src/main/java/org/session/libsession/utilities/dynamiclanguage/LanguageString.java @@ -7,8 +7,7 @@ import java.util.Locale; public final class LanguageString { - private LanguageString() { - } + private LanguageString() { } /** * @param languageString String in format language_REGION, e.g. en_US diff --git a/libsession/src/main/java/org/session/libsession/utilities/preferences/ProfileKeyUtil.java b/libsession/src/main/java/org/session/libsession/utilities/preferences/ProfileKeyUtil.java index 990164238c..3f7646c9ea 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/preferences/ProfileKeyUtil.java +++ b/libsession/src/main/java/org/session/libsession/utilities/preferences/ProfileKeyUtil.java @@ -1,6 +1,5 @@ package org.session.libsession.utilities.preferences; - import android.content.Context; import androidx.annotation.NonNull; import androidx.annotation.Nullable; diff --git a/libsession/src/main/java/org/session/libsession/utilities/task/SnackbarAsyncTask.java b/libsession/src/main/java/org/session/libsession/utilities/task/SnackbarAsyncTask.java index 3b899c0a2f..6ef5ca2ecb 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/task/SnackbarAsyncTask.java +++ b/libsession/src/main/java/org/session/libsession/utilities/task/SnackbarAsyncTask.java @@ -10,7 +10,6 @@ public abstract class SnackbarAsyncTask extends AsyncTask implements View.OnClickListener { - private final View view; private final String snackbarText; private final String snackbarActionText; diff --git a/libsession/src/main/java/org/session/libsession/utilities/views/Stub.java b/libsession/src/main/java/org/session/libsession/utilities/views/Stub.java index a8ab3866e1..292f051247 100644 --- a/libsession/src/main/java/org/session/libsession/utilities/views/Stub.java +++ b/libsession/src/main/java/org/session/libsession/utilities/views/Stub.java @@ -1,6 +1,5 @@ package org.session.libsession.utilities.views; - import android.view.ViewStub; import androidx.annotation.NonNull; From 25307068e8e06648eb313a663ff595011ea992b6 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Mon, 26 Apr 2021 11:06:00 +1000 Subject: [PATCH 05/13] Match iOS protobuf --- .../MessageReceiverHandler.kt | 80 - .../sending_receiving/MessageSender.kt | 4 +- .../MessageSenderClosedGroup.kt | 17 - .../org/session/libsession/snode/SnodeAPI.kt | 2 +- libsignal/protobuf/Makefile | 1 - libsignal/protobuf/SignalService.proto | 169 +- libsignal/protobuf/UnidentifiedDelivery.proto | 40 - .../api/crypto/SignalServiceCipher.java | 99 +- .../api/messages/SignalServiceEnvelope.java | 4 +- .../internal/push/SignalServiceProtos.java | 14098 +--------------- 10 files changed, 459 insertions(+), 14055 deletions(-) delete mode 100644 libsignal/protobuf/UnidentifiedDelivery.proto diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt index fc1b28e1cc..567b4ad021 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt @@ -233,13 +233,11 @@ fun MessageReceiver.handleVisibleMessage(message: VisibleMessage, proto: SignalS private fun MessageReceiver.handleClosedGroupControlMessage(message: ClosedGroupControlMessage) { when (message.kind!!) { is ClosedGroupControlMessage.Kind.New -> handleNewClosedGroup(message) - is ClosedGroupControlMessage.Kind.Update -> handleClosedGroupUpdated(message) is ClosedGroupControlMessage.Kind.EncryptionKeyPair -> handleClosedGroupEncryptionKeyPair(message) is ClosedGroupControlMessage.Kind.NameChange -> handleClosedGroupNameChanged(message) is ClosedGroupControlMessage.Kind.MembersAdded -> handleClosedGroupMembersAdded(message) is ClosedGroupControlMessage.Kind.MembersRemoved -> handleClosedGroupMembersRemoved(message) is ClosedGroupControlMessage.Kind.MemberLeft -> handleClosedGroupMemberLeft(message) - is ClosedGroupControlMessage.Kind.EncryptionKeyPairRequest -> handleClosedGroupEncryptionKeyPairRequest(message) } } @@ -283,59 +281,6 @@ private fun handleNewClosedGroup(sender: String, sentTimestamp: Long, groupPubli PushNotificationAPI.performOperation(PushNotificationAPI.ClosedGroupOperation.Subscribe, groupPublicKey, storage.getUserPublicKey()!!) } -private fun MessageReceiver.handleClosedGroupUpdated(message: ClosedGroupControlMessage) { - // Prepare - val context = MessagingConfiguration.shared.context - val storage = MessagingConfiguration.shared.storage - val senderPublicKey = message.sender ?: return - val kind = message.kind!! as? ClosedGroupControlMessage.Kind.Update ?: return - val groupPublicKey = message.groupPublicKey ?: return - val userPublicKey = storage.getUserPublicKey()!! - // Unwrap the message - val name = kind.name - val members = kind.members.map { it.toByteArray().toHexString() } - val groupID = GroupUtil.doubleEncodeGroupID(groupPublicKey) - val group = storage.getGroup(groupID) ?: run { - Log.d("Loki", "Ignoring closed group info message for nonexistent group.") - return - } - if (!group.isActive) { - Log.d("Loki", "Ignoring closed group info message for inactive group") - return - } - val oldMembers = group.members.map { it.serialize() } - // Check common group update logic - if (!isValidGroupUpdate(group, message.sentTimestamp!!, senderPublicKey)) { - return - } - // Check that the admin wasn't removed unless the group was destroyed entirely - if (!members.contains(group.admins.first().toString()) && members.isNotEmpty()) { - android.util.Log.d("Loki", "Ignoring invalid closed group update message.") - return - } - // Remove the group from the user's set of public keys to poll for if the current user was removed - val wasCurrentUserRemoved = !members.contains(userPublicKey) - if (wasCurrentUserRemoved) { - disableLocalGroupAndUnsubscribe(groupPublicKey, groupID, userPublicKey) - } - // Generate and distribute a new encryption key pair if needed - val wasAnyUserRemoved = (members.toSet().intersect(oldMembers) != oldMembers.toSet()) - val isCurrentUserAdmin = group.admins.map { it.toString() }.contains(userPublicKey) - if (wasAnyUserRemoved && isCurrentUserAdmin) { - MessageSender.generateAndSendNewEncryptionKeyPair(groupPublicKey, members) - } - // Update the group - storage.updateTitle(groupID, name) - if (!wasCurrentUserRemoved) { - // The call below sets isActive to true, so if the user is leaving we have to use groupDB.remove(...) instead - storage.updateMembers(groupID, members.map { Address.fromSerialized(it) }) - } - // Notify the user - val wasSenderRemoved = !members.contains(senderPublicKey) - val type = if (wasSenderRemoved) SignalServiceGroup.Type.QUIT else SignalServiceGroup.Type.MEMBER_REMOVED - storage.insertIncomingInfoMessage(context, senderPublicKey, groupID, type, name, members, group.admins.map { it.toString() }, message.sentTimestamp!!) -} - private fun MessageReceiver.handleClosedGroupEncryptionKeyPair(message: ClosedGroupControlMessage) { // Prepare val storage = MessagingConfiguration.shared.storage @@ -565,31 +510,6 @@ private fun MessageReceiver.handleClosedGroupMemberLeft(message: ClosedGroupCont } } -private fun MessageReceiver.handleClosedGroupEncryptionKeyPairRequest(message: ClosedGroupControlMessage) { - val storage = MessagingConfiguration.shared.storage - val senderPublicKey = message.sender ?: return - val userPublicKey = storage.getUserPublicKey()!! - if (message.kind!! !is ClosedGroupControlMessage.Kind.EncryptionKeyPairRequest) return - if (senderPublicKey == userPublicKey) { - Log.d("Loki", "Ignoring invalid closed group update.") - return - } - val groupPublicKey = message.groupPublicKey ?: return - val groupID = GroupUtil.doubleEncodeGroupID(groupPublicKey) - val group = storage.getGroup(groupID) ?: run { - Log.d("Loki", "Ignoring closed group info message for nonexistent group.") - return - } - if (!isValidGroupUpdate(group, message.sentTimestamp!!, senderPublicKey)) { return } - val encryptionKeyPair = pendingKeyPair[groupPublicKey]?.orNull() - ?: storage.getLatestClosedGroupEncryptionKeyPair(groupPublicKey) - if (encryptionKeyPair == null) { - Log.d("Loki", "Couldn't get encryption key pair for closed group.") - } else { - MessageSender.sendEncryptionKeyPair(groupPublicKey, encryptionKeyPair, setOf(senderPublicKey), targetUser = senderPublicKey, force = false) - } -} - private fun isValidGroupUpdate(group: GroupRecord, sentTimestamp: Long, senderPublicKey: String): Boolean { diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt index bea27664a8..3847e70659 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt @@ -135,11 +135,11 @@ object MessageSender { val senderPublicKey: String when (destination) { is Destination.Contact -> { - kind = SignalServiceProtos.Envelope.Type.UNIDENTIFIED_SENDER + kind = SignalServiceProtos.Envelope.Type.SESSION_MESSAGE senderPublicKey = "" } is Destination.ClosedGroup -> { - kind = SignalServiceProtos.Envelope.Type.CLOSED_GROUP_CIPHERTEXT + kind = SignalServiceProtos.Envelope.Type.CLOSED_GROUP_MESSAGE senderPublicKey = destination.groupPublicKey } is Destination.OpenGroup -> throw Error.PreconditionFailure("Destination should not be open groups!") diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroup.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroup.kt index 143fa7fb3f..bcd824f3a5 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroup.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroup.kt @@ -278,23 +278,6 @@ fun MessageSender.sendEncryptionKeyPair(groupPublicKey: String, newKeyPair: ECKe } } -/// Note: Shouldn't currently be in use. -fun MessageSender.requestEncryptionKeyPair(groupPublicKey: String) { - val storage = MessagingConfiguration.shared.storage - val groupID = GroupUtil.doubleEncodeGroupID(groupPublicKey) - val group = storage.getGroup(groupID) ?: run { - Log.d("Loki", "Can't request encryption key pair for nonexistent closed group.") - throw Error.NoThread - } - val members = group.members.map { it.serialize() }.toSet() - if (!members.contains(storage.getUserPublicKey()!!)) return - // Send the request to the group - val sentTime = System.currentTimeMillis() - val closedGroupControlMessage = ClosedGroupControlMessage(ClosedGroupControlMessage.Kind.EncryptionKeyPairRequest()) - closedGroupControlMessage.sentTimestamp = sentTime - send(closedGroupControlMessage, Address.fromSerialized(groupID)) -} - fun MessageSender.sendLatestEncryptionKeyPair(publicKey: String, groupPublicKey: String) { val storage = MessagingConfiguration.shared.storage val groupID = GroupUtil.doubleEncodeGroupID(groupPublicKey) diff --git a/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt b/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt index 0cfda8f2d8..1d90331e9a 100644 --- a/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt +++ b/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt @@ -46,7 +46,7 @@ object SnodeAPI { private val targetSwarmSnodeCount = 2 private val useOnionRequests = true - internal val useTestnet = true + internal val useTestnet = false // Error internal sealed class Error(val description: String) : Exception(description) { diff --git a/libsignal/protobuf/Makefile b/libsignal/protobuf/Makefile index 7b3b733754..77fe09c08b 100644 --- a/libsignal/protobuf/Makefile +++ b/libsignal/protobuf/Makefile @@ -1,4 +1,3 @@ all: protoc25 --java_out=../src/main/java/ SignalService.proto WebSocketResources.proto - protoc25 --java_out=../src/main/java/ UnidentifiedDelivery.proto diff --git a/libsignal/protobuf/SignalService.proto b/libsignal/protobuf/SignalService.proto index 614b5e65f2..c748919c4a 100644 --- a/libsignal/protobuf/SignalService.proto +++ b/libsignal/protobuf/SignalService.proto @@ -8,8 +8,8 @@ option java_outer_classname = "SignalServiceProtos"; message Envelope { enum Type { - UNIDENTIFIED_SENDER = 6; - CLOSED_GROUP_CIPHERTEXT = 7; + SESSION_MESSAGE = 6; + CLOSED_GROUP_MESSAGE = 7; } // @required @@ -17,39 +17,32 @@ message Envelope { optional string source = 2; optional uint32 sourceDevice = 7; // @required - optional uint64 timestamp = 5; + required uint64 timestamp = 5; optional bytes content = 8; optional uint64 serverTimestamp = 10; } message TypingMessage { - enum Action { - STARTED = 0; - STOPPED = 1; - } + enum Action { + STARTED = 0; + STOPPED = 1; + } - // @required - optional uint64 timestamp = 1; - // @required - optional Action action = 2; + // @required + required uint64 timestamp = 1; + // @required + required Action action = 2; } message Content { - optional DataMessage dataMessage = 1; - optional ReceiptMessage receiptMessage = 5; - optional TypingMessage typingMessage = 6; - optional ConfigurationMessage configurationMessage = 7; + optional DataMessage dataMessage = 1; + optional ReceiptMessage receiptMessage = 5; + optional TypingMessage typingMessage = 6; + optional ConfigurationMessage configurationMessage = 7; optional DataExtractionNotification dataExtractionNotification = 82; } -message ClosedGroupCiphertextMessageWrapper { - // @required - optional bytes ciphertext = 1; - // @required - optional bytes ephemeralPublicKey = 2; -} - message KeyPair { // @required required bytes publicKey = 1; @@ -90,87 +83,16 @@ message DataMessage { } // @required - optional uint64 id = 1; + required uint64 id = 1; // @required - optional string author = 2; + required string author = 2; optional string text = 3; repeated QuotedAttachment attachments = 4; } - message Contact { - - message Name { - optional string givenName = 1; - optional string familyName = 2; - optional string prefix = 3; - optional string suffix = 4; - optional string middleName = 5; - optional string displayName = 6; - } - - message Phone { - - enum Type { - HOME = 1; - MOBILE = 2; - WORK = 3; - CUSTOM = 4; - } - - optional string value = 1; - optional Type type = 2; - optional string label = 3; - } - - message Email { - - enum Type { - HOME = 1; - MOBILE = 2; - WORK = 3; - CUSTOM = 4; - } - - optional string value = 1; - optional Type type = 2; - optional string label = 3; - } - - message PostalAddress { - - enum Type { - HOME = 1; - WORK = 2; - CUSTOM = 3; - } - - optional Type type = 1; - optional string label = 2; - optional string street = 3; - optional string pobox = 4; - optional string neighborhood = 5; - optional string city = 6; - optional string region = 7; - optional string postcode = 8; - optional string country = 9; - } - - message Avatar { - optional AttachmentPointer avatar = 1; - optional bool isProfile = 2; - } - - optional Name name = 1; - repeated Phone number = 3; - repeated Email email = 4; - repeated PostalAddress address = 5; - optional Avatar avatar = 6; - optional string organization = 7; - } - message Preview { // @required - optional string url = 1; + required string url = 1; optional string title = 2; optional AttachmentPointer image = 3; } @@ -184,13 +106,11 @@ message DataMessage { enum Type { NEW = 1; // publicKey, name, encryptionKeyPair, members, admins - UPDATE = 2; // name, members ENCRYPTION_KEY_PAIR = 3; // publicKey, wrappers NAME_CHANGE = 4; // name MEMBERS_ADDED = 5; // members MEMBERS_REMOVED = 6; // members MEMBER_LEFT = 7; - ENCRYPTION_KEY_PAIR_REQUEST = 8; } message KeyPairWrapper { @@ -218,12 +138,10 @@ message DataMessage { optional bytes profileKey = 6; optional uint64 timestamp = 7; optional Quote quote = 8; - repeated Contact contact = 9; repeated Preview preview = 10; optional LokiProfile profile = 101; optional ClosedGroupControlMessage closedGroupControlMessage = 104; optional string syncTarget = 105; - optional PublicChatInfo publicChatInfo = 999; } message ConfigurationMessage { @@ -261,7 +179,7 @@ message ReceiptMessage { } // @required - optional Type type = 1; + required Type type = 1; repeated uint64 timestamp = 2; } @@ -272,7 +190,7 @@ message AttachmentPointer { } // @required - optional fixed64 id = 1; + required fixed64 id = 1; optional string contentType = 2; optional bytes key = 3; optional uint32 size = 4; @@ -304,51 +222,4 @@ message GroupContext { repeated string members = 4; optional AttachmentPointer avatar = 5; repeated string admins = 6; - - // Loki - These fields are only used internally for the Android code base. - // This is so that we can differentiate adding/kicking. - // DO NOT USE WHEN SENDING MESSAGES. - repeated string newMembers = 998; - repeated string removedMembers = 999; -} - -message ContactDetails { - - message Avatar { - optional string contentType = 1; - optional uint32 length = 2; - } - - // @required - optional string number = 1; - optional string name = 2; - optional Avatar avatar = 3; - optional string color = 4; - optional bytes profileKey = 6; - optional bool blocked = 7; - optional uint32 expireTimer = 8; - optional string nickname = 101; -} - -message GroupDetails { - - message Avatar { - optional string contentType = 1; - optional uint32 length = 2; - } - - // @required - optional bytes id = 1; - optional string name = 2; - repeated string members = 3; - optional Avatar avatar = 4; - optional bool active = 5 [default = true]; - optional uint32 expireTimer = 6; - optional string color = 7; - optional bool blocked = 8; - repeated string admins = 9; -} - -message PublicChatInfo { // Intended for internal use only - optional uint64 serverID = 1; } diff --git a/libsignal/protobuf/UnidentifiedDelivery.proto b/libsignal/protobuf/UnidentifiedDelivery.proto deleted file mode 100644 index 2cb548b9e3..0000000000 --- a/libsignal/protobuf/UnidentifiedDelivery.proto +++ /dev/null @@ -1,40 +0,0 @@ -syntax = "proto2"; - -package signal; - -option java_package = "org.session.libsignal.metadata"; -option java_outer_classname = "SignalProtos"; - -message ServerCertificate { - message Certificate { - optional uint32 id = 1; - optional bytes key = 2; - } - - optional bytes certificate = 1; - optional bytes signature = 2; -} - -message SenderCertificate { - optional string sender = 1; - optional uint32 senderDevice = 2; -} - -message UnidentifiedSenderMessage { - - message Message { - enum Type { - PREKEY_MESSAGE = 1; - MESSAGE = 2; - FALLBACK_MESSAGE = 3; - } - - optional Type type = 1; - optional SenderCertificate senderCertificate = 2; - optional bytes content = 3; - } - - optional bytes ephemeralPublic = 1; - optional bytes encryptedStatic = 2; - optional bytes encryptedMessage = 3; -} \ No newline at end of file diff --git a/libsignal/src/main/java/org/session/libsignal/service/api/crypto/SignalServiceCipher.java b/libsignal/src/main/java/org/session/libsignal/service/api/crypto/SignalServiceCipher.java index bb7e9c21d3..a8c2ca0bd9 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/api/crypto/SignalServiceCipher.java +++ b/libsignal/src/main/java/org/session/libsignal/service/api/crypto/SignalServiceCipher.java @@ -36,6 +36,7 @@ import org.session.libsignal.service.loki.api.crypto.SessionProtocol; import org.session.libsignal.service.loki.api.crypto.SessionProtocolUtilities; import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol; +import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -153,7 +154,6 @@ public class SignalServiceCipher { List attachments = new LinkedList(); boolean expirationUpdate = ((content.getFlags() & DataMessage.Flags.EXPIRATION_TIMER_UPDATE_VALUE) != 0); SignalServiceDataMessage.Quote quote = createQuote(content); - List sharedContacts = createSharedContacts(content); List previews = createPreviews(content); ClosedGroupControlMessage closedGroupControlMessage = content.getClosedGroupControlMessage(); String syncTarget = content.getSyncTarget(); @@ -176,7 +176,7 @@ public class SignalServiceCipher { expirationUpdate, content.hasProfileKey() ? content.getProfileKey().toByteArray() : null, quote, - sharedContacts, + new ArrayList<>(), previews, closedGroupControlMessage, syncTarget); @@ -245,101 +245,6 @@ public class SignalServiceCipher { return results; } - private List createSharedContacts(DataMessage content) { - if (content.getContactCount() <= 0) return null; - - List results = new LinkedList(); - - for (DataMessage.Contact contact : content.getContactList()) { - SharedContact.Builder builder = SharedContact.newBuilder() - .setName(SharedContact.Name.newBuilder() - .setDisplay(contact.getName().getDisplayName()) - .setFamily(contact.getName().getFamilyName()) - .setGiven(contact.getName().getGivenName()) - .setMiddle(contact.getName().getMiddleName()) - .setPrefix(contact.getName().getPrefix()) - .setSuffix(contact.getName().getSuffix()) - .build()); - - if (contact.getAddressCount() > 0) { - for (DataMessage.Contact.PostalAddress address : contact.getAddressList()) { - SharedContact.PostalAddress.Type type = SharedContact.PostalAddress.Type.HOME; - - switch (address.getType()) { - case WORK: type = SharedContact.PostalAddress.Type.WORK; break; - case HOME: type = SharedContact.PostalAddress.Type.HOME; break; - case CUSTOM: type = SharedContact.PostalAddress.Type.CUSTOM; break; - } - - builder.withAddress(SharedContact.PostalAddress.newBuilder() - .setCity(address.getCity()) - .setCountry(address.getCountry()) - .setLabel(address.getLabel()) - .setNeighborhood(address.getNeighborhood()) - .setPobox(address.getPobox()) - .setPostcode(address.getPostcode()) - .setRegion(address.getRegion()) - .setStreet(address.getStreet()) - .setType(type) - .build()); - } - } - - if (contact.getNumberCount() > 0) { - for (DataMessage.Contact.Phone phone : contact.getNumberList()) { - SharedContact.Phone.Type type = SharedContact.Phone.Type.HOME; - - switch (phone.getType()) { - case HOME: type = SharedContact.Phone.Type.HOME; break; - case WORK: type = SharedContact.Phone.Type.WORK; break; - case MOBILE: type = SharedContact.Phone.Type.MOBILE; break; - case CUSTOM: type = SharedContact.Phone.Type.CUSTOM; break; - } - - builder.withPhone(SharedContact.Phone.newBuilder() - .setLabel(phone.getLabel()) - .setType(type) - .setValue(phone.getValue()) - .build()); - } - } - - if (contact.getEmailCount() > 0) { - for (DataMessage.Contact.Email email : contact.getEmailList()) { - SharedContact.Email.Type type = SharedContact.Email.Type.HOME; - - switch (email.getType()) { - case HOME: type = SharedContact.Email.Type.HOME; break; - case WORK: type = SharedContact.Email.Type.WORK; break; - case MOBILE: type = SharedContact.Email.Type.MOBILE; break; - case CUSTOM: type = SharedContact.Email.Type.CUSTOM; break; - } - - builder.withEmail(SharedContact.Email.newBuilder() - .setLabel(email.getLabel()) - .setType(type) - .setValue(email.getValue()) - .build()); - } - } - - if (contact.hasAvatar()) { - builder.setAvatar(SharedContact.Avatar.newBuilder() - .withAttachment(createAttachmentPointer(contact.getAvatar().getAvatar())) - .withProfileFlag(contact.getAvatar().getIsProfile()) - .build()); - } - - if (contact.hasOrganization()) { - builder.withOrganization(contact.getOrganization()); - } - - results.add(builder.build()); - } - - return results; - } - private SignalServiceAttachmentPointer createAttachmentPointer(AttachmentPointer pointer) { return new SignalServiceAttachmentPointer(pointer.getId(), pointer.getContentType(), diff --git a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceEnvelope.java b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceEnvelope.java index 273fcdffc1..88236d64fe 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceEnvelope.java +++ b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceEnvelope.java @@ -133,10 +133,10 @@ public class SignalServiceEnvelope { } public boolean isUnidentifiedSender() { - return envelope.getType().getNumber() == Envelope.Type.UNIDENTIFIED_SENDER_VALUE; + return envelope.getType().getNumber() == Envelope.Type.SESSION_MESSAGE_VALUE; } public boolean isClosedGroupCiphertext() { - return envelope.getType().getNumber() == Envelope.Type.CLOSED_GROUP_CIPHERTEXT_VALUE; + return envelope.getType().getNumber() == Envelope.Type.CLOSED_GROUP_MESSAGE_VALUE; } } diff --git a/libsignal/src/main/java/org/session/libsignal/service/internal/push/SignalServiceProtos.java b/libsignal/src/main/java/org/session/libsignal/service/internal/push/SignalServiceProtos.java index 0e4feba1ed..50aa3e4792 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/internal/push/SignalServiceProtos.java +++ b/libsignal/src/main/java/org/session/libsignal/service/internal/push/SignalServiceProtos.java @@ -54,9 +54,9 @@ public final class SignalServiceProtos { */ int getSourceDevice(); - // optional uint64 timestamp = 5; + // required uint64 timestamp = 5; /** - * optional uint64 timestamp = 5; + * required uint64 timestamp = 5; * *
      * @required
@@ -64,7 +64,7 @@ public final class SignalServiceProtos {
      */
     boolean hasTimestamp();
     /**
-     * optional uint64 timestamp = 5;
+     * required uint64 timestamp = 5;
      *
      * 
      * @required
@@ -224,31 +224,31 @@ public final class SignalServiceProtos {
     public enum Type
         implements com.google.protobuf.ProtocolMessageEnum {
       /**
-       * UNIDENTIFIED_SENDER = 6;
+       * SESSION_MESSAGE = 6;
        */
-      UNIDENTIFIED_SENDER(0, 6),
+      SESSION_MESSAGE(0, 6),
       /**
-       * CLOSED_GROUP_CIPHERTEXT = 7;
+       * CLOSED_GROUP_MESSAGE = 7;
        */
-      CLOSED_GROUP_CIPHERTEXT(1, 7),
+      CLOSED_GROUP_MESSAGE(1, 7),
       ;
 
       /**
-       * UNIDENTIFIED_SENDER = 6;
+       * SESSION_MESSAGE = 6;
        */
-      public static final int UNIDENTIFIED_SENDER_VALUE = 6;
+      public static final int SESSION_MESSAGE_VALUE = 6;
       /**
-       * CLOSED_GROUP_CIPHERTEXT = 7;
+       * CLOSED_GROUP_MESSAGE = 7;
        */
-      public static final int CLOSED_GROUP_CIPHERTEXT_VALUE = 7;
+      public static final int CLOSED_GROUP_MESSAGE_VALUE = 7;
 
 
       public final int getNumber() { return value; }
 
       public static Type valueOf(int value) {
         switch (value) {
-          case 6: return UNIDENTIFIED_SENDER;
-          case 7: return CLOSED_GROUP_CIPHERTEXT;
+          case 6: return SESSION_MESSAGE;
+          case 7: return CLOSED_GROUP_MESSAGE;
           default: return null;
         }
       }
@@ -384,11 +384,11 @@ public final class SignalServiceProtos {
       return sourceDevice_;
     }
 
-    // optional uint64 timestamp = 5;
+    // required uint64 timestamp = 5;
     public static final int TIMESTAMP_FIELD_NUMBER = 5;
     private long timestamp_;
     /**
-     * optional uint64 timestamp = 5;
+     * required uint64 timestamp = 5;
      *
      * 
      * @required
@@ -398,7 +398,7 @@ public final class SignalServiceProtos {
       return ((bitField0_ & 0x00000008) == 0x00000008);
     }
     /**
-     * optional uint64 timestamp = 5;
+     * required uint64 timestamp = 5;
      *
      * 
      * @required
@@ -441,7 +441,7 @@ public final class SignalServiceProtos {
     }
 
     private void initFields() {
-      type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.Envelope.Type.UNIDENTIFIED_SENDER;
+      type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.Envelope.Type.SESSION_MESSAGE;
       source_ = "";
       sourceDevice_ = 0;
       timestamp_ = 0L;
@@ -457,6 +457,10 @@ public final class SignalServiceProtos {
         memoizedIsInitialized = 0;
         return false;
       }
+      if (!hasTimestamp()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
       memoizedIsInitialized = 1;
       return true;
     }
@@ -631,7 +635,7 @@ public final class SignalServiceProtos {
 
       public Builder clear() {
         super.clear();
-        type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.Envelope.Type.UNIDENTIFIED_SENDER;
+        type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.Envelope.Type.SESSION_MESSAGE;
         bitField0_ = (bitField0_ & ~0x00000001);
         source_ = "";
         bitField0_ = (bitField0_ & ~0x00000002);
@@ -740,6 +744,10 @@ public final class SignalServiceProtos {
           
           return false;
         }
+        if (!hasTimestamp()) {
+          
+          return false;
+        }
         return true;
       }
 
@@ -763,7 +771,7 @@ public final class SignalServiceProtos {
       private int bitField0_;
 
       // required .signalservice.Envelope.Type type = 1;
-      private org.session.libsignal.service.internal.push.SignalServiceProtos.Envelope.Type type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.Envelope.Type.UNIDENTIFIED_SENDER;
+      private org.session.libsignal.service.internal.push.SignalServiceProtos.Envelope.Type type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.Envelope.Type.SESSION_MESSAGE;
       /**
        * required .signalservice.Envelope.Type type = 1;
        *
@@ -809,7 +817,7 @@ public final class SignalServiceProtos {
        */
       public Builder clearType() {
         bitField0_ = (bitField0_ & ~0x00000001);
-        type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.Envelope.Type.UNIDENTIFIED_SENDER;
+        type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.Envelope.Type.SESSION_MESSAGE;
         onChanged();
         return this;
       }
@@ -921,10 +929,10 @@ public final class SignalServiceProtos {
         return this;
       }
 
-      // optional uint64 timestamp = 5;
+      // required uint64 timestamp = 5;
       private long timestamp_ ;
       /**
-       * optional uint64 timestamp = 5;
+       * required uint64 timestamp = 5;
        *
        * 
        * @required
@@ -934,7 +942,7 @@ public final class SignalServiceProtos {
         return ((bitField0_ & 0x00000008) == 0x00000008);
       }
       /**
-       * optional uint64 timestamp = 5;
+       * required uint64 timestamp = 5;
        *
        * 
        * @required
@@ -944,7 +952,7 @@ public final class SignalServiceProtos {
         return timestamp_;
       }
       /**
-       * optional uint64 timestamp = 5;
+       * required uint64 timestamp = 5;
        *
        * 
        * @required
@@ -957,7 +965,7 @@ public final class SignalServiceProtos {
         return this;
       }
       /**
-       * optional uint64 timestamp = 5;
+       * required uint64 timestamp = 5;
        *
        * 
        * @required
@@ -1053,9 +1061,9 @@ public final class SignalServiceProtos {
   public interface TypingMessageOrBuilder
       extends com.google.protobuf.MessageOrBuilder {
 
-    // optional uint64 timestamp = 1;
+    // required uint64 timestamp = 1;
     /**
-     * optional uint64 timestamp = 1;
+     * required uint64 timestamp = 1;
      *
      * 
      * @required
@@ -1063,7 +1071,7 @@ public final class SignalServiceProtos {
      */
     boolean hasTimestamp();
     /**
-     * optional uint64 timestamp = 1;
+     * required uint64 timestamp = 1;
      *
      * 
      * @required
@@ -1071,9 +1079,9 @@ public final class SignalServiceProtos {
      */
     long getTimestamp();
 
-    // optional .signalservice.TypingMessage.Action action = 2;
+    // required .signalservice.TypingMessage.Action action = 2;
     /**
-     * optional .signalservice.TypingMessage.Action action = 2;
+     * required .signalservice.TypingMessage.Action action = 2;
      *
      * 
      * @required
@@ -1081,7 +1089,7 @@ public final class SignalServiceProtos {
      */
     boolean hasAction();
     /**
-     * optional .signalservice.TypingMessage.Action action = 2;
+     * required .signalservice.TypingMessage.Action action = 2;
      *
      * 
      * @required
@@ -1278,11 +1286,11 @@ public final class SignalServiceProtos {
     }
 
     private int bitField0_;
-    // optional uint64 timestamp = 1;
+    // required uint64 timestamp = 1;
     public static final int TIMESTAMP_FIELD_NUMBER = 1;
     private long timestamp_;
     /**
-     * optional uint64 timestamp = 1;
+     * required uint64 timestamp = 1;
      *
      * 
      * @required
@@ -1292,7 +1300,7 @@ public final class SignalServiceProtos {
       return ((bitField0_ & 0x00000001) == 0x00000001);
     }
     /**
-     * optional uint64 timestamp = 1;
+     * required uint64 timestamp = 1;
      *
      * 
      * @required
@@ -1302,11 +1310,11 @@ public final class SignalServiceProtos {
       return timestamp_;
     }
 
-    // optional .signalservice.TypingMessage.Action action = 2;
+    // required .signalservice.TypingMessage.Action action = 2;
     public static final int ACTION_FIELD_NUMBER = 2;
     private org.session.libsignal.service.internal.push.SignalServiceProtos.TypingMessage.Action action_;
     /**
-     * optional .signalservice.TypingMessage.Action action = 2;
+     * required .signalservice.TypingMessage.Action action = 2;
      *
      * 
      * @required
@@ -1316,7 +1324,7 @@ public final class SignalServiceProtos {
       return ((bitField0_ & 0x00000002) == 0x00000002);
     }
     /**
-     * optional .signalservice.TypingMessage.Action action = 2;
+     * required .signalservice.TypingMessage.Action action = 2;
      *
      * 
      * @required
@@ -1335,6 +1343,14 @@ public final class SignalServiceProtos {
       byte isInitialized = memoizedIsInitialized;
       if (isInitialized != -1) return isInitialized == 1;
 
+      if (!hasTimestamp()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
+      if (!hasAction()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
       memoizedIsInitialized = 1;
       return true;
     }
@@ -1548,6 +1564,14 @@ public final class SignalServiceProtos {
       }
 
       public final boolean isInitialized() {
+        if (!hasTimestamp()) {
+          
+          return false;
+        }
+        if (!hasAction()) {
+          
+          return false;
+        }
         return true;
       }
 
@@ -1570,10 +1594,10 @@ public final class SignalServiceProtos {
       }
       private int bitField0_;
 
-      // optional uint64 timestamp = 1;
+      // required uint64 timestamp = 1;
       private long timestamp_ ;
       /**
-       * optional uint64 timestamp = 1;
+       * required uint64 timestamp = 1;
        *
        * 
        * @required
@@ -1583,7 +1607,7 @@ public final class SignalServiceProtos {
         return ((bitField0_ & 0x00000001) == 0x00000001);
       }
       /**
-       * optional uint64 timestamp = 1;
+       * required uint64 timestamp = 1;
        *
        * 
        * @required
@@ -1593,7 +1617,7 @@ public final class SignalServiceProtos {
         return timestamp_;
       }
       /**
-       * optional uint64 timestamp = 1;
+       * required uint64 timestamp = 1;
        *
        * 
        * @required
@@ -1606,7 +1630,7 @@ public final class SignalServiceProtos {
         return this;
       }
       /**
-       * optional uint64 timestamp = 1;
+       * required uint64 timestamp = 1;
        *
        * 
        * @required
@@ -1619,10 +1643,10 @@ public final class SignalServiceProtos {
         return this;
       }
 
-      // optional .signalservice.TypingMessage.Action action = 2;
+      // required .signalservice.TypingMessage.Action action = 2;
       private org.session.libsignal.service.internal.push.SignalServiceProtos.TypingMessage.Action action_ = org.session.libsignal.service.internal.push.SignalServiceProtos.TypingMessage.Action.STARTED;
       /**
-       * optional .signalservice.TypingMessage.Action action = 2;
+       * required .signalservice.TypingMessage.Action action = 2;
        *
        * 
        * @required
@@ -1632,7 +1656,7 @@ public final class SignalServiceProtos {
         return ((bitField0_ & 0x00000002) == 0x00000002);
       }
       /**
-       * optional .signalservice.TypingMessage.Action action = 2;
+       * required .signalservice.TypingMessage.Action action = 2;
        *
        * 
        * @required
@@ -1642,7 +1666,7 @@ public final class SignalServiceProtos {
         return action_;
       }
       /**
-       * optional .signalservice.TypingMessage.Action action = 2;
+       * required .signalservice.TypingMessage.Action action = 2;
        *
        * 
        * @required
@@ -1658,7 +1682,7 @@ public final class SignalServiceProtos {
         return this;
       }
       /**
-       * optional .signalservice.TypingMessage.Action action = 2;
+       * required .signalservice.TypingMessage.Action action = 2;
        *
        * 
        * @required
@@ -2039,6 +2063,18 @@ public final class SignalServiceProtos {
           return false;
         }
       }
+      if (hasReceiptMessage()) {
+        if (!getReceiptMessage().isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
+      if (hasTypingMessage()) {
+        if (!getTypingMessage().isInitialized()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+      }
       if (hasConfigurationMessage()) {
         if (!getConfigurationMessage().isInitialized()) {
           memoizedIsInitialized = 0;
@@ -2363,6 +2399,18 @@ public final class SignalServiceProtos {
             return false;
           }
         }
+        if (hasReceiptMessage()) {
+          if (!getReceiptMessage().isInitialized()) {
+            
+            return false;
+          }
+        }
+        if (hasTypingMessage()) {
+          if (!getTypingMessage().isInitialized()) {
+            
+            return false;
+          }
+        }
         if (hasConfigurationMessage()) {
           if (!getConfigurationMessage().isInitialized()) {
             
@@ -2993,553 +3041,6 @@ public final class SignalServiceProtos {
     // @@protoc_insertion_point(class_scope:signalservice.Content)
   }
 
-  public interface ClosedGroupCiphertextMessageWrapperOrBuilder
-      extends com.google.protobuf.MessageOrBuilder {
-
-    // optional bytes ciphertext = 1;
-    /**
-     * optional bytes ciphertext = 1;
-     *
-     * 
-     * @required
-     * 
- */ - boolean hasCiphertext(); - /** - * optional bytes ciphertext = 1; - * - *
-     * @required
-     * 
- */ - com.google.protobuf.ByteString getCiphertext(); - - // optional bytes ephemeralPublicKey = 2; - /** - * optional bytes ephemeralPublicKey = 2; - * - *
-     * @required
-     * 
- */ - boolean hasEphemeralPublicKey(); - /** - * optional bytes ephemeralPublicKey = 2; - * - *
-     * @required
-     * 
- */ - com.google.protobuf.ByteString getEphemeralPublicKey(); - } - /** - * Protobuf type {@code signalservice.ClosedGroupCiphertextMessageWrapper} - */ - public static final class ClosedGroupCiphertextMessageWrapper extends - com.google.protobuf.GeneratedMessage - implements ClosedGroupCiphertextMessageWrapperOrBuilder { - // Use ClosedGroupCiphertextMessageWrapper.newBuilder() to construct. - private ClosedGroupCiphertextMessageWrapper(com.google.protobuf.GeneratedMessage.Builder builder) { - super(builder); - this.unknownFields = builder.getUnknownFields(); - } - private ClosedGroupCiphertextMessageWrapper(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } - - private static final ClosedGroupCiphertextMessageWrapper defaultInstance; - public static ClosedGroupCiphertextMessageWrapper getDefaultInstance() { - return defaultInstance; - } - - public ClosedGroupCiphertextMessageWrapper getDefaultInstanceForType() { - return defaultInstance; - } - - private final com.google.protobuf.UnknownFieldSet unknownFields; - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private ClosedGroupCiphertextMessageWrapper( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - initFields(); - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - default: { - if (!parseUnknownField(input, unknownFields, - extensionRegistry, tag)) { - done = true; - } - break; - } - case 10: { - bitField0_ |= 0x00000001; - ciphertext_ = input.readBytes(); - break; - } - case 18: { - bitField0_ |= 0x00000002; - ephemeralPublicKey_ = input.readBytes(); - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e.getMessage()).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_ClosedGroupCiphertextMessageWrapper_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_ClosedGroupCiphertextMessageWrapper_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper.class, org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper.Builder.class); - } - - public static com.google.protobuf.Parser PARSER = - new com.google.protobuf.AbstractParser() { - public ClosedGroupCiphertextMessageWrapper parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new ClosedGroupCiphertextMessageWrapper(input, extensionRegistry); - } - }; - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - private int bitField0_; - // optional bytes ciphertext = 1; - public static final int CIPHERTEXT_FIELD_NUMBER = 1; - private com.google.protobuf.ByteString ciphertext_; - /** - * optional bytes ciphertext = 1; - * - *
-     * @required
-     * 
- */ - public boolean hasCiphertext() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional bytes ciphertext = 1; - * - *
-     * @required
-     * 
- */ - public com.google.protobuf.ByteString getCiphertext() { - return ciphertext_; - } - - // optional bytes ephemeralPublicKey = 2; - public static final int EPHEMERALPUBLICKEY_FIELD_NUMBER = 2; - private com.google.protobuf.ByteString ephemeralPublicKey_; - /** - * optional bytes ephemeralPublicKey = 2; - * - *
-     * @required
-     * 
- */ - public boolean hasEphemeralPublicKey() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional bytes ephemeralPublicKey = 2; - * - *
-     * @required
-     * 
- */ - public com.google.protobuf.ByteString getEphemeralPublicKey() { - return ephemeralPublicKey_; - } - - private void initFields() { - ciphertext_ = com.google.protobuf.ByteString.EMPTY; - ephemeralPublicKey_ = com.google.protobuf.ByteString.EMPTY; - } - private byte memoizedIsInitialized = -1; - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized != -1) return isInitialized == 1; - - memoizedIsInitialized = 1; - return true; - } - - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - getSerializedSize(); - if (((bitField0_ & 0x00000001) == 0x00000001)) { - output.writeBytes(1, ciphertext_); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - output.writeBytes(2, ephemeralPublicKey_); - } - getUnknownFields().writeTo(output); - } - - private int memoizedSerializedSize = -1; - public int getSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (((bitField0_ & 0x00000001) == 0x00000001)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, ciphertext_); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(2, ephemeralPublicKey_); - } - size += getUnknownFields().getSerializedSize(); - memoizedSerializedSize = size; - return size; - } - - private static final long serialVersionUID = 0L; - @java.lang.Override - protected java.lang.Object writeReplace() - throws java.io.ObjectStreamException { - return super.writeReplace(); - } - - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper parseFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - - public static Builder newBuilder() { return Builder.create(); } - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper prototype) { - return newBuilder().mergeFrom(prototype); - } - public Builder toBuilder() { return newBuilder(this); } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code signalservice.ClosedGroupCiphertextMessageWrapper} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessage.Builder - implements org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapperOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_ClosedGroupCiphertextMessageWrapper_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_ClosedGroupCiphertextMessageWrapper_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper.class, org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper.Builder.class); - } - - // Construct using org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { - } - } - private static Builder create() { - return new Builder(); - } - - public Builder clear() { - super.clear(); - ciphertext_ = com.google.protobuf.ByteString.EMPTY; - bitField0_ = (bitField0_ & ~0x00000001); - ephemeralPublicKey_ = com.google.protobuf.ByteString.EMPTY; - bitField0_ = (bitField0_ & ~0x00000002); - return this; - } - - public Builder clone() { - return create().mergeFrom(buildPartial()); - } - - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_ClosedGroupCiphertextMessageWrapper_descriptor; - } - - public org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper getDefaultInstanceForType() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper.getDefaultInstance(); - } - - public org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper build() { - org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - public org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper buildPartial() { - org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper result = new org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) == 0x00000001)) { - to_bitField0_ |= 0x00000001; - } - result.ciphertext_ = ciphertext_; - if (((from_bitField0_ & 0x00000002) == 0x00000002)) { - to_bitField0_ |= 0x00000002; - } - result.ephemeralPublicKey_ = ephemeralPublicKey_; - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper) { - return mergeFrom((org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper other) { - if (other == org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper.getDefaultInstance()) return this; - if (other.hasCiphertext()) { - setCiphertext(other.getCiphertext()); - } - if (other.hasEphemeralPublicKey()) { - setEphemeralPublicKey(other.getEphemeralPublicKey()); - } - this.mergeUnknownFields(other.getUnknownFields()); - return this; - } - - public final boolean isInitialized() { - return true; - } - - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (org.session.libsignal.service.internal.push.SignalServiceProtos.ClosedGroupCiphertextMessageWrapper) e.getUnfinishedMessage(); - throw e; - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - // optional bytes ciphertext = 1; - private com.google.protobuf.ByteString ciphertext_ = com.google.protobuf.ByteString.EMPTY; - /** - * optional bytes ciphertext = 1; - * - *
-       * @required
-       * 
- */ - public boolean hasCiphertext() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional bytes ciphertext = 1; - * - *
-       * @required
-       * 
- */ - public com.google.protobuf.ByteString getCiphertext() { - return ciphertext_; - } - /** - * optional bytes ciphertext = 1; - * - *
-       * @required
-       * 
- */ - public Builder setCiphertext(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - ciphertext_ = value; - onChanged(); - return this; - } - /** - * optional bytes ciphertext = 1; - * - *
-       * @required
-       * 
- */ - public Builder clearCiphertext() { - bitField0_ = (bitField0_ & ~0x00000001); - ciphertext_ = getDefaultInstance().getCiphertext(); - onChanged(); - return this; - } - - // optional bytes ephemeralPublicKey = 2; - private com.google.protobuf.ByteString ephemeralPublicKey_ = com.google.protobuf.ByteString.EMPTY; - /** - * optional bytes ephemeralPublicKey = 2; - * - *
-       * @required
-       * 
- */ - public boolean hasEphemeralPublicKey() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional bytes ephemeralPublicKey = 2; - * - *
-       * @required
-       * 
- */ - public com.google.protobuf.ByteString getEphemeralPublicKey() { - return ephemeralPublicKey_; - } - /** - * optional bytes ephemeralPublicKey = 2; - * - *
-       * @required
-       * 
- */ - public Builder setEphemeralPublicKey(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000002; - ephemeralPublicKey_ = value; - onChanged(); - return this; - } - /** - * optional bytes ephemeralPublicKey = 2; - * - *
-       * @required
-       * 
- */ - public Builder clearEphemeralPublicKey() { - bitField0_ = (bitField0_ & ~0x00000002); - ephemeralPublicKey_ = getDefaultInstance().getEphemeralPublicKey(); - onChanged(); - return this; - } - - // @@protoc_insertion_point(builder_scope:signalservice.ClosedGroupCiphertextMessageWrapper) - } - - static { - defaultInstance = new ClosedGroupCiphertextMessageWrapper(true); - defaultInstance.initFields(); - } - - // @@protoc_insertion_point(class_scope:signalservice.ClosedGroupCiphertextMessageWrapper) - } - public interface KeyPairOrBuilder extends com.google.protobuf.MessageOrBuilder { @@ -4830,31 +4331,6 @@ public final class SignalServiceProtos { */ org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.QuoteOrBuilder getQuoteOrBuilder(); - // repeated .signalservice.DataMessage.Contact contact = 9; - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - java.util.List - getContactList(); - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact getContact(int index); - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - int getContactCount(); - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - java.util.List - getContactOrBuilderList(); - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.ContactOrBuilder getContactOrBuilder( - int index); - // repeated .signalservice.DataMessage.Preview preview = 10; /** * repeated .signalservice.DataMessage.Preview preview = 10; @@ -4922,20 +4398,6 @@ public final class SignalServiceProtos { */ com.google.protobuf.ByteString getSyncTargetBytes(); - - // optional .signalservice.PublicChatInfo publicChatInfo = 999; - /** - * optional .signalservice.PublicChatInfo publicChatInfo = 999; - */ - boolean hasPublicChatInfo(); - /** - * optional .signalservice.PublicChatInfo publicChatInfo = 999; - */ - org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo getPublicChatInfo(); - /** - * optional .signalservice.PublicChatInfo publicChatInfo = 999; - */ - org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfoOrBuilder getPublicChatInfoOrBuilder(); } /** * Protobuf type {@code signalservice.DataMessage} @@ -5047,18 +4509,10 @@ public final class SignalServiceProtos { bitField0_ |= 0x00000040; break; } - case 74: { - if (!((mutable_bitField0_ & 0x00000100) == 0x00000100)) { - contact_ = new java.util.ArrayList(); - mutable_bitField0_ |= 0x00000100; - } - contact_.add(input.readMessage(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PARSER, extensionRegistry)); - break; - } case 82: { - if (!((mutable_bitField0_ & 0x00000200) == 0x00000200)) { + if (!((mutable_bitField0_ & 0x00000100) == 0x00000100)) { preview_ = new java.util.ArrayList(); - mutable_bitField0_ |= 0x00000200; + mutable_bitField0_ |= 0x00000100; } preview_.add(input.readMessage(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Preview.PARSER, extensionRegistry)); break; @@ -5094,19 +4548,6 @@ public final class SignalServiceProtos { syncTarget_ = input.readBytes(); break; } - case 7994: { - org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo.Builder subBuilder = null; - if (((bitField0_ & 0x00000400) == 0x00000400)) { - subBuilder = publicChatInfo_.toBuilder(); - } - publicChatInfo_ = input.readMessage(org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo.PARSER, extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(publicChatInfo_); - publicChatInfo_ = subBuilder.buildPartial(); - } - bitField0_ |= 0x00000400; - break; - } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { @@ -5119,9 +4560,6 @@ public final class SignalServiceProtos { attachments_ = java.util.Collections.unmodifiableList(attachments_); } if (((mutable_bitField0_ & 0x00000100) == 0x00000100)) { - contact_ = java.util.Collections.unmodifiableList(contact_); - } - if (((mutable_bitField0_ & 0x00000200) == 0x00000200)) { preview_ = java.util.Collections.unmodifiableList(preview_); } this.unknownFields = unknownFields.build(); @@ -5231,9 +4669,9 @@ public final class SignalServiceProtos { public interface QuoteOrBuilder extends com.google.protobuf.MessageOrBuilder { - // optional uint64 id = 1; + // required uint64 id = 1; /** - * optional uint64 id = 1; + * required uint64 id = 1; * *
        * @required
@@ -5241,7 +4679,7 @@ public final class SignalServiceProtos {
        */
       boolean hasId();
       /**
-       * optional uint64 id = 1;
+       * required uint64 id = 1;
        *
        * 
        * @required
@@ -5249,9 +4687,9 @@ public final class SignalServiceProtos {
        */
       long getId();
 
-      // optional string author = 2;
+      // required string author = 2;
       /**
-       * optional string author = 2;
+       * required string author = 2;
        *
        * 
        * @required
@@ -5259,7 +4697,7 @@ public final class SignalServiceProtos {
        */
       boolean hasAuthor();
       /**
-       * optional string author = 2;
+       * required string author = 2;
        *
        * 
        * @required
@@ -5267,7 +4705,7 @@ public final class SignalServiceProtos {
        */
       java.lang.String getAuthor();
       /**
-       * optional string author = 2;
+       * required string author = 2;
        *
        * 
        * @required
@@ -5816,6 +5254,12 @@ public final class SignalServiceProtos {
           byte isInitialized = memoizedIsInitialized;
           if (isInitialized != -1) return isInitialized == 1;
 
+          if (hasThumbnail()) {
+            if (!getThumbnail().isInitialized()) {
+              memoizedIsInitialized = 0;
+              return false;
+            }
+          }
           memoizedIsInitialized = 1;
           return true;
         }
@@ -6074,6 +5518,12 @@ public final class SignalServiceProtos {
           }
 
           public final boolean isInitialized() {
+            if (hasThumbnail()) {
+              if (!getThumbnail().isInitialized()) {
+                
+                return false;
+              }
+            }
             return true;
           }
 
@@ -6406,11 +5856,11 @@ public final class SignalServiceProtos {
       }
 
       private int bitField0_;
-      // optional uint64 id = 1;
+      // required uint64 id = 1;
       public static final int ID_FIELD_NUMBER = 1;
       private long id_;
       /**
-       * optional uint64 id = 1;
+       * required uint64 id = 1;
        *
        * 
        * @required
@@ -6420,7 +5870,7 @@ public final class SignalServiceProtos {
         return ((bitField0_ & 0x00000001) == 0x00000001);
       }
       /**
-       * optional uint64 id = 1;
+       * required uint64 id = 1;
        *
        * 
        * @required
@@ -6430,11 +5880,11 @@ public final class SignalServiceProtos {
         return id_;
       }
 
-      // optional string author = 2;
+      // required string author = 2;
       public static final int AUTHOR_FIELD_NUMBER = 2;
       private java.lang.Object author_;
       /**
-       * optional string author = 2;
+       * required string author = 2;
        *
        * 
        * @required
@@ -6444,7 +5894,7 @@ public final class SignalServiceProtos {
         return ((bitField0_ & 0x00000002) == 0x00000002);
       }
       /**
-       * optional string author = 2;
+       * required string author = 2;
        *
        * 
        * @required
@@ -6465,7 +5915,7 @@ public final class SignalServiceProtos {
         }
       }
       /**
-       * optional string author = 2;
+       * required string author = 2;
        *
        * 
        * @required
@@ -6575,6 +6025,20 @@ public final class SignalServiceProtos {
         byte isInitialized = memoizedIsInitialized;
         if (isInitialized != -1) return isInitialized == 1;
 
+        if (!hasId()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+        if (!hasAuthor()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+        for (int i = 0; i < getAttachmentsCount(); i++) {
+          if (!getAttachments(i).isInitialized()) {
+            memoizedIsInitialized = 0;
+            return false;
+          }
+        }
         memoizedIsInitialized = 1;
         return true;
       }
@@ -6857,6 +6321,20 @@ public final class SignalServiceProtos {
         }
 
         public final boolean isInitialized() {
+          if (!hasId()) {
+            
+            return false;
+          }
+          if (!hasAuthor()) {
+            
+            return false;
+          }
+          for (int i = 0; i < getAttachmentsCount(); i++) {
+            if (!getAttachments(i).isInitialized()) {
+              
+              return false;
+            }
+          }
           return true;
         }
 
@@ -6879,10 +6357,10 @@ public final class SignalServiceProtos {
         }
         private int bitField0_;
 
-        // optional uint64 id = 1;
+        // required uint64 id = 1;
         private long id_ ;
         /**
-         * optional uint64 id = 1;
+         * required uint64 id = 1;
          *
          * 
          * @required
@@ -6892,7 +6370,7 @@ public final class SignalServiceProtos {
           return ((bitField0_ & 0x00000001) == 0x00000001);
         }
         /**
-         * optional uint64 id = 1;
+         * required uint64 id = 1;
          *
          * 
          * @required
@@ -6902,7 +6380,7 @@ public final class SignalServiceProtos {
           return id_;
         }
         /**
-         * optional uint64 id = 1;
+         * required uint64 id = 1;
          *
          * 
          * @required
@@ -6915,7 +6393,7 @@ public final class SignalServiceProtos {
           return this;
         }
         /**
-         * optional uint64 id = 1;
+         * required uint64 id = 1;
          *
          * 
          * @required
@@ -6928,10 +6406,10 @@ public final class SignalServiceProtos {
           return this;
         }
 
-        // optional string author = 2;
+        // required string author = 2;
         private java.lang.Object author_ = "";
         /**
-         * optional string author = 2;
+         * required string author = 2;
          *
          * 
          * @required
@@ -6941,7 +6419,7 @@ public final class SignalServiceProtos {
           return ((bitField0_ & 0x00000002) == 0x00000002);
         }
         /**
-         * optional string author = 2;
+         * required string author = 2;
          *
          * 
          * @required
@@ -6959,7 +6437,7 @@ public final class SignalServiceProtos {
           }
         }
         /**
-         * optional string author = 2;
+         * required string author = 2;
          *
          * 
          * @required
@@ -6979,7 +6457,7 @@ public final class SignalServiceProtos {
           }
         }
         /**
-         * optional string author = 2;
+         * required string author = 2;
          *
          * 
          * @required
@@ -6996,7 +6474,7 @@ public final class SignalServiceProtos {
           return this;
         }
         /**
-         * optional string author = 2;
+         * required string author = 2;
          *
          * 
          * @required
@@ -7009,7 +6487,7 @@ public final class SignalServiceProtos {
           return this;
         }
         /**
-         * optional string author = 2;
+         * required string author = 2;
          *
          * 
          * @required
@@ -7351,7170 +6829,12 @@ public final class SignalServiceProtos {
       // @@protoc_insertion_point(class_scope:signalservice.DataMessage.Quote)
     }
 
-    public interface ContactOrBuilder
-        extends com.google.protobuf.MessageOrBuilder {
-
-      // optional .signalservice.DataMessage.Contact.Name name = 1;
-      /**
-       * optional .signalservice.DataMessage.Contact.Name name = 1;
-       */
-      boolean hasName();
-      /**
-       * optional .signalservice.DataMessage.Contact.Name name = 1;
-       */
-      org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name getName();
-      /**
-       * optional .signalservice.DataMessage.Contact.Name name = 1;
-       */
-      org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.NameOrBuilder getNameOrBuilder();
-
-      // repeated .signalservice.DataMessage.Contact.Phone number = 3;
-      /**
-       * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-       */
-      java.util.List 
-          getNumberList();
-      /**
-       * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-       */
-      org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone getNumber(int index);
-      /**
-       * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-       */
-      int getNumberCount();
-      /**
-       * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-       */
-      java.util.List 
-          getNumberOrBuilderList();
-      /**
-       * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-       */
-      org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PhoneOrBuilder getNumberOrBuilder(
-          int index);
-
-      // repeated .signalservice.DataMessage.Contact.Email email = 4;
-      /**
-       * repeated .signalservice.DataMessage.Contact.Email email = 4;
-       */
-      java.util.List 
-          getEmailList();
-      /**
-       * repeated .signalservice.DataMessage.Contact.Email email = 4;
-       */
-      org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email getEmail(int index);
-      /**
-       * repeated .signalservice.DataMessage.Contact.Email email = 4;
-       */
-      int getEmailCount();
-      /**
-       * repeated .signalservice.DataMessage.Contact.Email email = 4;
-       */
-      java.util.List 
-          getEmailOrBuilderList();
-      /**
-       * repeated .signalservice.DataMessage.Contact.Email email = 4;
-       */
-      org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.EmailOrBuilder getEmailOrBuilder(
-          int index);
-
-      // repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-      /**
-       * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-       */
-      java.util.List 
-          getAddressList();
-      /**
-       * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-       */
-      org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress getAddress(int index);
-      /**
-       * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-       */
-      int getAddressCount();
-      /**
-       * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-       */
-      java.util.List 
-          getAddressOrBuilderList();
-      /**
-       * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-       */
-      org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddressOrBuilder getAddressOrBuilder(
-          int index);
-
-      // optional .signalservice.DataMessage.Contact.Avatar avatar = 6;
-      /**
-       * optional .signalservice.DataMessage.Contact.Avatar avatar = 6;
-       */
-      boolean hasAvatar();
-      /**
-       * optional .signalservice.DataMessage.Contact.Avatar avatar = 6;
-       */
-      org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar getAvatar();
-      /**
-       * optional .signalservice.DataMessage.Contact.Avatar avatar = 6;
-       */
-      org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.AvatarOrBuilder getAvatarOrBuilder();
-
-      // optional string organization = 7;
-      /**
-       * optional string organization = 7;
-       */
-      boolean hasOrganization();
-      /**
-       * optional string organization = 7;
-       */
-      java.lang.String getOrganization();
-      /**
-       * optional string organization = 7;
-       */
-      com.google.protobuf.ByteString
-          getOrganizationBytes();
-    }
-    /**
-     * Protobuf type {@code signalservice.DataMessage.Contact}
-     */
-    public static final class Contact extends
-        com.google.protobuf.GeneratedMessage
-        implements ContactOrBuilder {
-      // Use Contact.newBuilder() to construct.
-      private Contact(com.google.protobuf.GeneratedMessage.Builder builder) {
-        super(builder);
-        this.unknownFields = builder.getUnknownFields();
-      }
-      private Contact(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-      private static final Contact defaultInstance;
-      public static Contact getDefaultInstance() {
-        return defaultInstance;
-      }
-
-      public Contact getDefaultInstanceForType() {
-        return defaultInstance;
-      }
-
-      private final com.google.protobuf.UnknownFieldSet unknownFields;
-      @java.lang.Override
-      public final com.google.protobuf.UnknownFieldSet
-          getUnknownFields() {
-        return this.unknownFields;
-      }
-      private Contact(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        initFields();
-        int mutable_bitField0_ = 0;
-        com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-            com.google.protobuf.UnknownFieldSet.newBuilder();
-        try {
-          boolean done = false;
-          while (!done) {
-            int tag = input.readTag();
-            switch (tag) {
-              case 0:
-                done = true;
-                break;
-              default: {
-                if (!parseUnknownField(input, unknownFields,
-                                       extensionRegistry, tag)) {
-                  done = true;
-                }
-                break;
-              }
-              case 10: {
-                org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name.Builder subBuilder = null;
-                if (((bitField0_ & 0x00000001) == 0x00000001)) {
-                  subBuilder = name_.toBuilder();
-                }
-                name_ = input.readMessage(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name.PARSER, extensionRegistry);
-                if (subBuilder != null) {
-                  subBuilder.mergeFrom(name_);
-                  name_ = subBuilder.buildPartial();
-                }
-                bitField0_ |= 0x00000001;
-                break;
-              }
-              case 26: {
-                if (!((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
-                  number_ = new java.util.ArrayList();
-                  mutable_bitField0_ |= 0x00000002;
-                }
-                number_.add(input.readMessage(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.PARSER, extensionRegistry));
-                break;
-              }
-              case 34: {
-                if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
-                  email_ = new java.util.ArrayList();
-                  mutable_bitField0_ |= 0x00000004;
-                }
-                email_.add(input.readMessage(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.PARSER, extensionRegistry));
-                break;
-              }
-              case 42: {
-                if (!((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
-                  address_ = new java.util.ArrayList();
-                  mutable_bitField0_ |= 0x00000008;
-                }
-                address_.add(input.readMessage(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.PARSER, extensionRegistry));
-                break;
-              }
-              case 50: {
-                org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar.Builder subBuilder = null;
-                if (((bitField0_ & 0x00000002) == 0x00000002)) {
-                  subBuilder = avatar_.toBuilder();
-                }
-                avatar_ = input.readMessage(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar.PARSER, extensionRegistry);
-                if (subBuilder != null) {
-                  subBuilder.mergeFrom(avatar_);
-                  avatar_ = subBuilder.buildPartial();
-                }
-                bitField0_ |= 0x00000002;
-                break;
-              }
-              case 58: {
-                bitField0_ |= 0x00000004;
-                organization_ = input.readBytes();
-                break;
-              }
-            }
-          }
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          throw e.setUnfinishedMessage(this);
-        } catch (java.io.IOException e) {
-          throw new com.google.protobuf.InvalidProtocolBufferException(
-              e.getMessage()).setUnfinishedMessage(this);
-        } finally {
-          if (((mutable_bitField0_ & 0x00000002) == 0x00000002)) {
-            number_ = java.util.Collections.unmodifiableList(number_);
-          }
-          if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) {
-            email_ = java.util.Collections.unmodifiableList(email_);
-          }
-          if (((mutable_bitField0_ & 0x00000008) == 0x00000008)) {
-            address_ = java.util.Collections.unmodifiableList(address_);
-          }
-          this.unknownFields = unknownFields.build();
-          makeExtensionsImmutable();
-        }
-      }
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_descriptor;
-      }
-
-      protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.class, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Builder.class);
-      }
-
-      public static com.google.protobuf.Parser PARSER =
-          new com.google.protobuf.AbstractParser() {
-        public Contact parsePartialFrom(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return new Contact(input, extensionRegistry);
-        }
-      };
-
-      @java.lang.Override
-      public com.google.protobuf.Parser getParserForType() {
-        return PARSER;
-      }
-
-      public interface NameOrBuilder
-          extends com.google.protobuf.MessageOrBuilder {
-
-        // optional string givenName = 1;
-        /**
-         * optional string givenName = 1;
-         */
-        boolean hasGivenName();
-        /**
-         * optional string givenName = 1;
-         */
-        java.lang.String getGivenName();
-        /**
-         * optional string givenName = 1;
-         */
-        com.google.protobuf.ByteString
-            getGivenNameBytes();
-
-        // optional string familyName = 2;
-        /**
-         * optional string familyName = 2;
-         */
-        boolean hasFamilyName();
-        /**
-         * optional string familyName = 2;
-         */
-        java.lang.String getFamilyName();
-        /**
-         * optional string familyName = 2;
-         */
-        com.google.protobuf.ByteString
-            getFamilyNameBytes();
-
-        // optional string prefix = 3;
-        /**
-         * optional string prefix = 3;
-         */
-        boolean hasPrefix();
-        /**
-         * optional string prefix = 3;
-         */
-        java.lang.String getPrefix();
-        /**
-         * optional string prefix = 3;
-         */
-        com.google.protobuf.ByteString
-            getPrefixBytes();
-
-        // optional string suffix = 4;
-        /**
-         * optional string suffix = 4;
-         */
-        boolean hasSuffix();
-        /**
-         * optional string suffix = 4;
-         */
-        java.lang.String getSuffix();
-        /**
-         * optional string suffix = 4;
-         */
-        com.google.protobuf.ByteString
-            getSuffixBytes();
-
-        // optional string middleName = 5;
-        /**
-         * optional string middleName = 5;
-         */
-        boolean hasMiddleName();
-        /**
-         * optional string middleName = 5;
-         */
-        java.lang.String getMiddleName();
-        /**
-         * optional string middleName = 5;
-         */
-        com.google.protobuf.ByteString
-            getMiddleNameBytes();
-
-        // optional string displayName = 6;
-        /**
-         * optional string displayName = 6;
-         */
-        boolean hasDisplayName();
-        /**
-         * optional string displayName = 6;
-         */
-        java.lang.String getDisplayName();
-        /**
-         * optional string displayName = 6;
-         */
-        com.google.protobuf.ByteString
-            getDisplayNameBytes();
-      }
-      /**
-       * Protobuf type {@code signalservice.DataMessage.Contact.Name}
-       */
-      public static final class Name extends
-          com.google.protobuf.GeneratedMessage
-          implements NameOrBuilder {
-        // Use Name.newBuilder() to construct.
-        private Name(com.google.protobuf.GeneratedMessage.Builder builder) {
-          super(builder);
-          this.unknownFields = builder.getUnknownFields();
-        }
-        private Name(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-        private static final Name defaultInstance;
-        public static Name getDefaultInstance() {
-          return defaultInstance;
-        }
-
-        public Name getDefaultInstanceForType() {
-          return defaultInstance;
-        }
-
-        private final com.google.protobuf.UnknownFieldSet unknownFields;
-        @java.lang.Override
-        public final com.google.protobuf.UnknownFieldSet
-            getUnknownFields() {
-          return this.unknownFields;
-        }
-        private Name(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          initFields();
-          int mutable_bitField0_ = 0;
-          com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-              com.google.protobuf.UnknownFieldSet.newBuilder();
-          try {
-            boolean done = false;
-            while (!done) {
-              int tag = input.readTag();
-              switch (tag) {
-                case 0:
-                  done = true;
-                  break;
-                default: {
-                  if (!parseUnknownField(input, unknownFields,
-                                         extensionRegistry, tag)) {
-                    done = true;
-                  }
-                  break;
-                }
-                case 10: {
-                  bitField0_ |= 0x00000001;
-                  givenName_ = input.readBytes();
-                  break;
-                }
-                case 18: {
-                  bitField0_ |= 0x00000002;
-                  familyName_ = input.readBytes();
-                  break;
-                }
-                case 26: {
-                  bitField0_ |= 0x00000004;
-                  prefix_ = input.readBytes();
-                  break;
-                }
-                case 34: {
-                  bitField0_ |= 0x00000008;
-                  suffix_ = input.readBytes();
-                  break;
-                }
-                case 42: {
-                  bitField0_ |= 0x00000010;
-                  middleName_ = input.readBytes();
-                  break;
-                }
-                case 50: {
-                  bitField0_ |= 0x00000020;
-                  displayName_ = input.readBytes();
-                  break;
-                }
-              }
-            }
-          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-            throw e.setUnfinishedMessage(this);
-          } catch (java.io.IOException e) {
-            throw new com.google.protobuf.InvalidProtocolBufferException(
-                e.getMessage()).setUnfinishedMessage(this);
-          } finally {
-            this.unknownFields = unknownFields.build();
-            makeExtensionsImmutable();
-          }
-        }
-        public static final com.google.protobuf.Descriptors.Descriptor
-            getDescriptor() {
-          return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_Name_descriptor;
-        }
-
-        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-            internalGetFieldAccessorTable() {
-          return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_Name_fieldAccessorTable
-              .ensureFieldAccessorsInitialized(
-                  org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name.class, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name.Builder.class);
-        }
-
-        public static com.google.protobuf.Parser PARSER =
-            new com.google.protobuf.AbstractParser() {
-          public Name parsePartialFrom(
-              com.google.protobuf.CodedInputStream input,
-              com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-              throws com.google.protobuf.InvalidProtocolBufferException {
-            return new Name(input, extensionRegistry);
-          }
-        };
-
-        @java.lang.Override
-        public com.google.protobuf.Parser getParserForType() {
-          return PARSER;
-        }
-
-        private int bitField0_;
-        // optional string givenName = 1;
-        public static final int GIVENNAME_FIELD_NUMBER = 1;
-        private java.lang.Object givenName_;
-        /**
-         * optional string givenName = 1;
-         */
-        public boolean hasGivenName() {
-          return ((bitField0_ & 0x00000001) == 0x00000001);
-        }
-        /**
-         * optional string givenName = 1;
-         */
-        public java.lang.String getGivenName() {
-          java.lang.Object ref = givenName_;
-          if (ref instanceof java.lang.String) {
-            return (java.lang.String) ref;
-          } else {
-            com.google.protobuf.ByteString bs = 
-                (com.google.protobuf.ByteString) ref;
-            java.lang.String s = bs.toStringUtf8();
-            if (bs.isValidUtf8()) {
-              givenName_ = s;
-            }
-            return s;
-          }
-        }
-        /**
-         * optional string givenName = 1;
-         */
-        public com.google.protobuf.ByteString
-            getGivenNameBytes() {
-          java.lang.Object ref = givenName_;
-          if (ref instanceof java.lang.String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            givenName_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-
-        // optional string familyName = 2;
-        public static final int FAMILYNAME_FIELD_NUMBER = 2;
-        private java.lang.Object familyName_;
-        /**
-         * optional string familyName = 2;
-         */
-        public boolean hasFamilyName() {
-          return ((bitField0_ & 0x00000002) == 0x00000002);
-        }
-        /**
-         * optional string familyName = 2;
-         */
-        public java.lang.String getFamilyName() {
-          java.lang.Object ref = familyName_;
-          if (ref instanceof java.lang.String) {
-            return (java.lang.String) ref;
-          } else {
-            com.google.protobuf.ByteString bs = 
-                (com.google.protobuf.ByteString) ref;
-            java.lang.String s = bs.toStringUtf8();
-            if (bs.isValidUtf8()) {
-              familyName_ = s;
-            }
-            return s;
-          }
-        }
-        /**
-         * optional string familyName = 2;
-         */
-        public com.google.protobuf.ByteString
-            getFamilyNameBytes() {
-          java.lang.Object ref = familyName_;
-          if (ref instanceof java.lang.String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            familyName_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-
-        // optional string prefix = 3;
-        public static final int PREFIX_FIELD_NUMBER = 3;
-        private java.lang.Object prefix_;
-        /**
-         * optional string prefix = 3;
-         */
-        public boolean hasPrefix() {
-          return ((bitField0_ & 0x00000004) == 0x00000004);
-        }
-        /**
-         * optional string prefix = 3;
-         */
-        public java.lang.String getPrefix() {
-          java.lang.Object ref = prefix_;
-          if (ref instanceof java.lang.String) {
-            return (java.lang.String) ref;
-          } else {
-            com.google.protobuf.ByteString bs = 
-                (com.google.protobuf.ByteString) ref;
-            java.lang.String s = bs.toStringUtf8();
-            if (bs.isValidUtf8()) {
-              prefix_ = s;
-            }
-            return s;
-          }
-        }
-        /**
-         * optional string prefix = 3;
-         */
-        public com.google.protobuf.ByteString
-            getPrefixBytes() {
-          java.lang.Object ref = prefix_;
-          if (ref instanceof java.lang.String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            prefix_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-
-        // optional string suffix = 4;
-        public static final int SUFFIX_FIELD_NUMBER = 4;
-        private java.lang.Object suffix_;
-        /**
-         * optional string suffix = 4;
-         */
-        public boolean hasSuffix() {
-          return ((bitField0_ & 0x00000008) == 0x00000008);
-        }
-        /**
-         * optional string suffix = 4;
-         */
-        public java.lang.String getSuffix() {
-          java.lang.Object ref = suffix_;
-          if (ref instanceof java.lang.String) {
-            return (java.lang.String) ref;
-          } else {
-            com.google.protobuf.ByteString bs = 
-                (com.google.protobuf.ByteString) ref;
-            java.lang.String s = bs.toStringUtf8();
-            if (bs.isValidUtf8()) {
-              suffix_ = s;
-            }
-            return s;
-          }
-        }
-        /**
-         * optional string suffix = 4;
-         */
-        public com.google.protobuf.ByteString
-            getSuffixBytes() {
-          java.lang.Object ref = suffix_;
-          if (ref instanceof java.lang.String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            suffix_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-
-        // optional string middleName = 5;
-        public static final int MIDDLENAME_FIELD_NUMBER = 5;
-        private java.lang.Object middleName_;
-        /**
-         * optional string middleName = 5;
-         */
-        public boolean hasMiddleName() {
-          return ((bitField0_ & 0x00000010) == 0x00000010);
-        }
-        /**
-         * optional string middleName = 5;
-         */
-        public java.lang.String getMiddleName() {
-          java.lang.Object ref = middleName_;
-          if (ref instanceof java.lang.String) {
-            return (java.lang.String) ref;
-          } else {
-            com.google.protobuf.ByteString bs = 
-                (com.google.protobuf.ByteString) ref;
-            java.lang.String s = bs.toStringUtf8();
-            if (bs.isValidUtf8()) {
-              middleName_ = s;
-            }
-            return s;
-          }
-        }
-        /**
-         * optional string middleName = 5;
-         */
-        public com.google.protobuf.ByteString
-            getMiddleNameBytes() {
-          java.lang.Object ref = middleName_;
-          if (ref instanceof java.lang.String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            middleName_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-
-        // optional string displayName = 6;
-        public static final int DISPLAYNAME_FIELD_NUMBER = 6;
-        private java.lang.Object displayName_;
-        /**
-         * optional string displayName = 6;
-         */
-        public boolean hasDisplayName() {
-          return ((bitField0_ & 0x00000020) == 0x00000020);
-        }
-        /**
-         * optional string displayName = 6;
-         */
-        public java.lang.String getDisplayName() {
-          java.lang.Object ref = displayName_;
-          if (ref instanceof java.lang.String) {
-            return (java.lang.String) ref;
-          } else {
-            com.google.protobuf.ByteString bs = 
-                (com.google.protobuf.ByteString) ref;
-            java.lang.String s = bs.toStringUtf8();
-            if (bs.isValidUtf8()) {
-              displayName_ = s;
-            }
-            return s;
-          }
-        }
-        /**
-         * optional string displayName = 6;
-         */
-        public com.google.protobuf.ByteString
-            getDisplayNameBytes() {
-          java.lang.Object ref = displayName_;
-          if (ref instanceof java.lang.String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            displayName_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-
-        private void initFields() {
-          givenName_ = "";
-          familyName_ = "";
-          prefix_ = "";
-          suffix_ = "";
-          middleName_ = "";
-          displayName_ = "";
-        }
-        private byte memoizedIsInitialized = -1;
-        public final boolean isInitialized() {
-          byte isInitialized = memoizedIsInitialized;
-          if (isInitialized != -1) return isInitialized == 1;
-
-          memoizedIsInitialized = 1;
-          return true;
-        }
-
-        public void writeTo(com.google.protobuf.CodedOutputStream output)
-                            throws java.io.IOException {
-          getSerializedSize();
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
-            output.writeBytes(1, getGivenNameBytes());
-          }
-          if (((bitField0_ & 0x00000002) == 0x00000002)) {
-            output.writeBytes(2, getFamilyNameBytes());
-          }
-          if (((bitField0_ & 0x00000004) == 0x00000004)) {
-            output.writeBytes(3, getPrefixBytes());
-          }
-          if (((bitField0_ & 0x00000008) == 0x00000008)) {
-            output.writeBytes(4, getSuffixBytes());
-          }
-          if (((bitField0_ & 0x00000010) == 0x00000010)) {
-            output.writeBytes(5, getMiddleNameBytes());
-          }
-          if (((bitField0_ & 0x00000020) == 0x00000020)) {
-            output.writeBytes(6, getDisplayNameBytes());
-          }
-          getUnknownFields().writeTo(output);
-        }
-
-        private int memoizedSerializedSize = -1;
-        public int getSerializedSize() {
-          int size = memoizedSerializedSize;
-          if (size != -1) return size;
-
-          size = 0;
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeBytesSize(1, getGivenNameBytes());
-          }
-          if (((bitField0_ & 0x00000002) == 0x00000002)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeBytesSize(2, getFamilyNameBytes());
-          }
-          if (((bitField0_ & 0x00000004) == 0x00000004)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeBytesSize(3, getPrefixBytes());
-          }
-          if (((bitField0_ & 0x00000008) == 0x00000008)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeBytesSize(4, getSuffixBytes());
-          }
-          if (((bitField0_ & 0x00000010) == 0x00000010)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeBytesSize(5, getMiddleNameBytes());
-          }
-          if (((bitField0_ & 0x00000020) == 0x00000020)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeBytesSize(6, getDisplayNameBytes());
-          }
-          size += getUnknownFields().getSerializedSize();
-          memoizedSerializedSize = size;
-          return size;
-        }
-
-        private static final long serialVersionUID = 0L;
-        @java.lang.Override
-        protected java.lang.Object writeReplace()
-            throws java.io.ObjectStreamException {
-          return super.writeReplace();
-        }
-
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name parseFrom(
-            com.google.protobuf.ByteString data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return PARSER.parseFrom(data);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name parseFrom(
-            com.google.protobuf.ByteString data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return PARSER.parseFrom(data, extensionRegistry);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name parseFrom(byte[] data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return PARSER.parseFrom(data);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name parseFrom(
-            byte[] data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return PARSER.parseFrom(data, extensionRegistry);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name parseFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return PARSER.parseFrom(input);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name parseFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return PARSER.parseFrom(input, extensionRegistry);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name parseDelimitedFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return PARSER.parseDelimitedFrom(input);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name parseDelimitedFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return PARSER.parseDelimitedFrom(input, extensionRegistry);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name parseFrom(
-            com.google.protobuf.CodedInputStream input)
-            throws java.io.IOException {
-          return PARSER.parseFrom(input);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name parseFrom(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return PARSER.parseFrom(input, extensionRegistry);
-        }
-
-        public static Builder newBuilder() { return Builder.create(); }
-        public Builder newBuilderForType() { return newBuilder(); }
-        public static Builder newBuilder(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name prototype) {
-          return newBuilder().mergeFrom(prototype);
-        }
-        public Builder toBuilder() { return newBuilder(this); }
-
-        @java.lang.Override
-        protected Builder newBuilderForType(
-            com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-          Builder builder = new Builder(parent);
-          return builder;
-        }
-        /**
-         * Protobuf type {@code signalservice.DataMessage.Contact.Name}
-         */
-        public static final class Builder extends
-            com.google.protobuf.GeneratedMessage.Builder
-           implements org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.NameOrBuilder {
-          public static final com.google.protobuf.Descriptors.Descriptor
-              getDescriptor() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_Name_descriptor;
-          }
-
-          protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-              internalGetFieldAccessorTable() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_Name_fieldAccessorTable
-                .ensureFieldAccessorsInitialized(
-                    org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name.class, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name.Builder.class);
-          }
-
-          // Construct using org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name.newBuilder()
-          private Builder() {
-            maybeForceBuilderInitialization();
-          }
-
-          private Builder(
-              com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-            super(parent);
-            maybeForceBuilderInitialization();
-          }
-          private void maybeForceBuilderInitialization() {
-            if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-            }
-          }
-          private static Builder create() {
-            return new Builder();
-          }
-
-          public Builder clear() {
-            super.clear();
-            givenName_ = "";
-            bitField0_ = (bitField0_ & ~0x00000001);
-            familyName_ = "";
-            bitField0_ = (bitField0_ & ~0x00000002);
-            prefix_ = "";
-            bitField0_ = (bitField0_ & ~0x00000004);
-            suffix_ = "";
-            bitField0_ = (bitField0_ & ~0x00000008);
-            middleName_ = "";
-            bitField0_ = (bitField0_ & ~0x00000010);
-            displayName_ = "";
-            bitField0_ = (bitField0_ & ~0x00000020);
-            return this;
-          }
-
-          public Builder clone() {
-            return create().mergeFrom(buildPartial());
-          }
-
-          public com.google.protobuf.Descriptors.Descriptor
-              getDescriptorForType() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_Name_descriptor;
-          }
-
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name getDefaultInstanceForType() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name.getDefaultInstance();
-          }
-
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name build() {
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name result = buildPartial();
-            if (!result.isInitialized()) {
-              throw newUninitializedMessageException(result);
-            }
-            return result;
-          }
-
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name buildPartial() {
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name result = new org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name(this);
-            int from_bitField0_ = bitField0_;
-            int to_bitField0_ = 0;
-            if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-              to_bitField0_ |= 0x00000001;
-            }
-            result.givenName_ = givenName_;
-            if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
-              to_bitField0_ |= 0x00000002;
-            }
-            result.familyName_ = familyName_;
-            if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
-              to_bitField0_ |= 0x00000004;
-            }
-            result.prefix_ = prefix_;
-            if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
-              to_bitField0_ |= 0x00000008;
-            }
-            result.suffix_ = suffix_;
-            if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
-              to_bitField0_ |= 0x00000010;
-            }
-            result.middleName_ = middleName_;
-            if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
-              to_bitField0_ |= 0x00000020;
-            }
-            result.displayName_ = displayName_;
-            result.bitField0_ = to_bitField0_;
-            onBuilt();
-            return result;
-          }
-
-          public Builder mergeFrom(com.google.protobuf.Message other) {
-            if (other instanceof org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name) {
-              return mergeFrom((org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name)other);
-            } else {
-              super.mergeFrom(other);
-              return this;
-            }
-          }
-
-          public Builder mergeFrom(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name other) {
-            if (other == org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name.getDefaultInstance()) return this;
-            if (other.hasGivenName()) {
-              bitField0_ |= 0x00000001;
-              givenName_ = other.givenName_;
-              onChanged();
-            }
-            if (other.hasFamilyName()) {
-              bitField0_ |= 0x00000002;
-              familyName_ = other.familyName_;
-              onChanged();
-            }
-            if (other.hasPrefix()) {
-              bitField0_ |= 0x00000004;
-              prefix_ = other.prefix_;
-              onChanged();
-            }
-            if (other.hasSuffix()) {
-              bitField0_ |= 0x00000008;
-              suffix_ = other.suffix_;
-              onChanged();
-            }
-            if (other.hasMiddleName()) {
-              bitField0_ |= 0x00000010;
-              middleName_ = other.middleName_;
-              onChanged();
-            }
-            if (other.hasDisplayName()) {
-              bitField0_ |= 0x00000020;
-              displayName_ = other.displayName_;
-              onChanged();
-            }
-            this.mergeUnknownFields(other.getUnknownFields());
-            return this;
-          }
-
-          public final boolean isInitialized() {
-            return true;
-          }
-
-          public Builder mergeFrom(
-              com.google.protobuf.CodedInputStream input,
-              com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-              throws java.io.IOException {
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name parsedMessage = null;
-            try {
-              parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-            } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-              parsedMessage = (org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name) e.getUnfinishedMessage();
-              throw e;
-            } finally {
-              if (parsedMessage != null) {
-                mergeFrom(parsedMessage);
-              }
-            }
-            return this;
-          }
-          private int bitField0_;
-
-          // optional string givenName = 1;
-          private java.lang.Object givenName_ = "";
-          /**
-           * optional string givenName = 1;
-           */
-          public boolean hasGivenName() {
-            return ((bitField0_ & 0x00000001) == 0x00000001);
-          }
-          /**
-           * optional string givenName = 1;
-           */
-          public java.lang.String getGivenName() {
-            java.lang.Object ref = givenName_;
-            if (!(ref instanceof java.lang.String)) {
-              java.lang.String s = ((com.google.protobuf.ByteString) ref)
-                  .toStringUtf8();
-              givenName_ = s;
-              return s;
-            } else {
-              return (java.lang.String) ref;
-            }
-          }
-          /**
-           * optional string givenName = 1;
-           */
-          public com.google.protobuf.ByteString
-              getGivenNameBytes() {
-            java.lang.Object ref = givenName_;
-            if (ref instanceof String) {
-              com.google.protobuf.ByteString b = 
-                  com.google.protobuf.ByteString.copyFromUtf8(
-                      (java.lang.String) ref);
-              givenName_ = b;
-              return b;
-            } else {
-              return (com.google.protobuf.ByteString) ref;
-            }
-          }
-          /**
-           * optional string givenName = 1;
-           */
-          public Builder setGivenName(
-              java.lang.String value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000001;
-            givenName_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string givenName = 1;
-           */
-          public Builder clearGivenName() {
-            bitField0_ = (bitField0_ & ~0x00000001);
-            givenName_ = getDefaultInstance().getGivenName();
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string givenName = 1;
-           */
-          public Builder setGivenNameBytes(
-              com.google.protobuf.ByteString value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000001;
-            givenName_ = value;
-            onChanged();
-            return this;
-          }
-
-          // optional string familyName = 2;
-          private java.lang.Object familyName_ = "";
-          /**
-           * optional string familyName = 2;
-           */
-          public boolean hasFamilyName() {
-            return ((bitField0_ & 0x00000002) == 0x00000002);
-          }
-          /**
-           * optional string familyName = 2;
-           */
-          public java.lang.String getFamilyName() {
-            java.lang.Object ref = familyName_;
-            if (!(ref instanceof java.lang.String)) {
-              java.lang.String s = ((com.google.protobuf.ByteString) ref)
-                  .toStringUtf8();
-              familyName_ = s;
-              return s;
-            } else {
-              return (java.lang.String) ref;
-            }
-          }
-          /**
-           * optional string familyName = 2;
-           */
-          public com.google.protobuf.ByteString
-              getFamilyNameBytes() {
-            java.lang.Object ref = familyName_;
-            if (ref instanceof String) {
-              com.google.protobuf.ByteString b = 
-                  com.google.protobuf.ByteString.copyFromUtf8(
-                      (java.lang.String) ref);
-              familyName_ = b;
-              return b;
-            } else {
-              return (com.google.protobuf.ByteString) ref;
-            }
-          }
-          /**
-           * optional string familyName = 2;
-           */
-          public Builder setFamilyName(
-              java.lang.String value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000002;
-            familyName_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string familyName = 2;
-           */
-          public Builder clearFamilyName() {
-            bitField0_ = (bitField0_ & ~0x00000002);
-            familyName_ = getDefaultInstance().getFamilyName();
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string familyName = 2;
-           */
-          public Builder setFamilyNameBytes(
-              com.google.protobuf.ByteString value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000002;
-            familyName_ = value;
-            onChanged();
-            return this;
-          }
-
-          // optional string prefix = 3;
-          private java.lang.Object prefix_ = "";
-          /**
-           * optional string prefix = 3;
-           */
-          public boolean hasPrefix() {
-            return ((bitField0_ & 0x00000004) == 0x00000004);
-          }
-          /**
-           * optional string prefix = 3;
-           */
-          public java.lang.String getPrefix() {
-            java.lang.Object ref = prefix_;
-            if (!(ref instanceof java.lang.String)) {
-              java.lang.String s = ((com.google.protobuf.ByteString) ref)
-                  .toStringUtf8();
-              prefix_ = s;
-              return s;
-            } else {
-              return (java.lang.String) ref;
-            }
-          }
-          /**
-           * optional string prefix = 3;
-           */
-          public com.google.protobuf.ByteString
-              getPrefixBytes() {
-            java.lang.Object ref = prefix_;
-            if (ref instanceof String) {
-              com.google.protobuf.ByteString b = 
-                  com.google.protobuf.ByteString.copyFromUtf8(
-                      (java.lang.String) ref);
-              prefix_ = b;
-              return b;
-            } else {
-              return (com.google.protobuf.ByteString) ref;
-            }
-          }
-          /**
-           * optional string prefix = 3;
-           */
-          public Builder setPrefix(
-              java.lang.String value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000004;
-            prefix_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string prefix = 3;
-           */
-          public Builder clearPrefix() {
-            bitField0_ = (bitField0_ & ~0x00000004);
-            prefix_ = getDefaultInstance().getPrefix();
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string prefix = 3;
-           */
-          public Builder setPrefixBytes(
-              com.google.protobuf.ByteString value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000004;
-            prefix_ = value;
-            onChanged();
-            return this;
-          }
-
-          // optional string suffix = 4;
-          private java.lang.Object suffix_ = "";
-          /**
-           * optional string suffix = 4;
-           */
-          public boolean hasSuffix() {
-            return ((bitField0_ & 0x00000008) == 0x00000008);
-          }
-          /**
-           * optional string suffix = 4;
-           */
-          public java.lang.String getSuffix() {
-            java.lang.Object ref = suffix_;
-            if (!(ref instanceof java.lang.String)) {
-              java.lang.String s = ((com.google.protobuf.ByteString) ref)
-                  .toStringUtf8();
-              suffix_ = s;
-              return s;
-            } else {
-              return (java.lang.String) ref;
-            }
-          }
-          /**
-           * optional string suffix = 4;
-           */
-          public com.google.protobuf.ByteString
-              getSuffixBytes() {
-            java.lang.Object ref = suffix_;
-            if (ref instanceof String) {
-              com.google.protobuf.ByteString b = 
-                  com.google.protobuf.ByteString.copyFromUtf8(
-                      (java.lang.String) ref);
-              suffix_ = b;
-              return b;
-            } else {
-              return (com.google.protobuf.ByteString) ref;
-            }
-          }
-          /**
-           * optional string suffix = 4;
-           */
-          public Builder setSuffix(
-              java.lang.String value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000008;
-            suffix_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string suffix = 4;
-           */
-          public Builder clearSuffix() {
-            bitField0_ = (bitField0_ & ~0x00000008);
-            suffix_ = getDefaultInstance().getSuffix();
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string suffix = 4;
-           */
-          public Builder setSuffixBytes(
-              com.google.protobuf.ByteString value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000008;
-            suffix_ = value;
-            onChanged();
-            return this;
-          }
-
-          // optional string middleName = 5;
-          private java.lang.Object middleName_ = "";
-          /**
-           * optional string middleName = 5;
-           */
-          public boolean hasMiddleName() {
-            return ((bitField0_ & 0x00000010) == 0x00000010);
-          }
-          /**
-           * optional string middleName = 5;
-           */
-          public java.lang.String getMiddleName() {
-            java.lang.Object ref = middleName_;
-            if (!(ref instanceof java.lang.String)) {
-              java.lang.String s = ((com.google.protobuf.ByteString) ref)
-                  .toStringUtf8();
-              middleName_ = s;
-              return s;
-            } else {
-              return (java.lang.String) ref;
-            }
-          }
-          /**
-           * optional string middleName = 5;
-           */
-          public com.google.protobuf.ByteString
-              getMiddleNameBytes() {
-            java.lang.Object ref = middleName_;
-            if (ref instanceof String) {
-              com.google.protobuf.ByteString b = 
-                  com.google.protobuf.ByteString.copyFromUtf8(
-                      (java.lang.String) ref);
-              middleName_ = b;
-              return b;
-            } else {
-              return (com.google.protobuf.ByteString) ref;
-            }
-          }
-          /**
-           * optional string middleName = 5;
-           */
-          public Builder setMiddleName(
-              java.lang.String value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000010;
-            middleName_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string middleName = 5;
-           */
-          public Builder clearMiddleName() {
-            bitField0_ = (bitField0_ & ~0x00000010);
-            middleName_ = getDefaultInstance().getMiddleName();
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string middleName = 5;
-           */
-          public Builder setMiddleNameBytes(
-              com.google.protobuf.ByteString value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000010;
-            middleName_ = value;
-            onChanged();
-            return this;
-          }
-
-          // optional string displayName = 6;
-          private java.lang.Object displayName_ = "";
-          /**
-           * optional string displayName = 6;
-           */
-          public boolean hasDisplayName() {
-            return ((bitField0_ & 0x00000020) == 0x00000020);
-          }
-          /**
-           * optional string displayName = 6;
-           */
-          public java.lang.String getDisplayName() {
-            java.lang.Object ref = displayName_;
-            if (!(ref instanceof java.lang.String)) {
-              java.lang.String s = ((com.google.protobuf.ByteString) ref)
-                  .toStringUtf8();
-              displayName_ = s;
-              return s;
-            } else {
-              return (java.lang.String) ref;
-            }
-          }
-          /**
-           * optional string displayName = 6;
-           */
-          public com.google.protobuf.ByteString
-              getDisplayNameBytes() {
-            java.lang.Object ref = displayName_;
-            if (ref instanceof String) {
-              com.google.protobuf.ByteString b = 
-                  com.google.protobuf.ByteString.copyFromUtf8(
-                      (java.lang.String) ref);
-              displayName_ = b;
-              return b;
-            } else {
-              return (com.google.protobuf.ByteString) ref;
-            }
-          }
-          /**
-           * optional string displayName = 6;
-           */
-          public Builder setDisplayName(
-              java.lang.String value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000020;
-            displayName_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string displayName = 6;
-           */
-          public Builder clearDisplayName() {
-            bitField0_ = (bitField0_ & ~0x00000020);
-            displayName_ = getDefaultInstance().getDisplayName();
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string displayName = 6;
-           */
-          public Builder setDisplayNameBytes(
-              com.google.protobuf.ByteString value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000020;
-            displayName_ = value;
-            onChanged();
-            return this;
-          }
-
-          // @@protoc_insertion_point(builder_scope:signalservice.DataMessage.Contact.Name)
-        }
-
-        static {
-          defaultInstance = new Name(true);
-          defaultInstance.initFields();
-        }
-
-        // @@protoc_insertion_point(class_scope:signalservice.DataMessage.Contact.Name)
-      }
-
-      public interface PhoneOrBuilder
-          extends com.google.protobuf.MessageOrBuilder {
-
-        // optional string value = 1;
-        /**
-         * optional string value = 1;
-         */
-        boolean hasValue();
-        /**
-         * optional string value = 1;
-         */
-        java.lang.String getValue();
-        /**
-         * optional string value = 1;
-         */
-        com.google.protobuf.ByteString
-            getValueBytes();
-
-        // optional .signalservice.DataMessage.Contact.Phone.Type type = 2;
-        /**
-         * optional .signalservice.DataMessage.Contact.Phone.Type type = 2;
-         */
-        boolean hasType();
-        /**
-         * optional .signalservice.DataMessage.Contact.Phone.Type type = 2;
-         */
-        org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Type getType();
-
-        // optional string label = 3;
-        /**
-         * optional string label = 3;
-         */
-        boolean hasLabel();
-        /**
-         * optional string label = 3;
-         */
-        java.lang.String getLabel();
-        /**
-         * optional string label = 3;
-         */
-        com.google.protobuf.ByteString
-            getLabelBytes();
-      }
-      /**
-       * Protobuf type {@code signalservice.DataMessage.Contact.Phone}
-       */
-      public static final class Phone extends
-          com.google.protobuf.GeneratedMessage
-          implements PhoneOrBuilder {
-        // Use Phone.newBuilder() to construct.
-        private Phone(com.google.protobuf.GeneratedMessage.Builder builder) {
-          super(builder);
-          this.unknownFields = builder.getUnknownFields();
-        }
-        private Phone(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-        private static final Phone defaultInstance;
-        public static Phone getDefaultInstance() {
-          return defaultInstance;
-        }
-
-        public Phone getDefaultInstanceForType() {
-          return defaultInstance;
-        }
-
-        private final com.google.protobuf.UnknownFieldSet unknownFields;
-        @java.lang.Override
-        public final com.google.protobuf.UnknownFieldSet
-            getUnknownFields() {
-          return this.unknownFields;
-        }
-        private Phone(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          initFields();
-          int mutable_bitField0_ = 0;
-          com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-              com.google.protobuf.UnknownFieldSet.newBuilder();
-          try {
-            boolean done = false;
-            while (!done) {
-              int tag = input.readTag();
-              switch (tag) {
-                case 0:
-                  done = true;
-                  break;
-                default: {
-                  if (!parseUnknownField(input, unknownFields,
-                                         extensionRegistry, tag)) {
-                    done = true;
-                  }
-                  break;
-                }
-                case 10: {
-                  bitField0_ |= 0x00000001;
-                  value_ = input.readBytes();
-                  break;
-                }
-                case 16: {
-                  int rawValue = input.readEnum();
-                  org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Type value = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Type.valueOf(rawValue);
-                  if (value == null) {
-                    unknownFields.mergeVarintField(2, rawValue);
-                  } else {
-                    bitField0_ |= 0x00000002;
-                    type_ = value;
-                  }
-                  break;
-                }
-                case 26: {
-                  bitField0_ |= 0x00000004;
-                  label_ = input.readBytes();
-                  break;
-                }
-              }
-            }
-          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-            throw e.setUnfinishedMessage(this);
-          } catch (java.io.IOException e) {
-            throw new com.google.protobuf.InvalidProtocolBufferException(
-                e.getMessage()).setUnfinishedMessage(this);
-          } finally {
-            this.unknownFields = unknownFields.build();
-            makeExtensionsImmutable();
-          }
-        }
-        public static final com.google.protobuf.Descriptors.Descriptor
-            getDescriptor() {
-          return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_Phone_descriptor;
-        }
-
-        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-            internalGetFieldAccessorTable() {
-          return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_Phone_fieldAccessorTable
-              .ensureFieldAccessorsInitialized(
-                  org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.class, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Builder.class);
-        }
-
-        public static com.google.protobuf.Parser PARSER =
-            new com.google.protobuf.AbstractParser() {
-          public Phone parsePartialFrom(
-              com.google.protobuf.CodedInputStream input,
-              com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-              throws com.google.protobuf.InvalidProtocolBufferException {
-            return new Phone(input, extensionRegistry);
-          }
-        };
-
-        @java.lang.Override
-        public com.google.protobuf.Parser getParserForType() {
-          return PARSER;
-        }
-
-        /**
-         * Protobuf enum {@code signalservice.DataMessage.Contact.Phone.Type}
-         */
-        public enum Type
-            implements com.google.protobuf.ProtocolMessageEnum {
-          /**
-           * HOME = 1;
-           */
-          HOME(0, 1),
-          /**
-           * MOBILE = 2;
-           */
-          MOBILE(1, 2),
-          /**
-           * WORK = 3;
-           */
-          WORK(2, 3),
-          /**
-           * CUSTOM = 4;
-           */
-          CUSTOM(3, 4),
-          ;
-
-          /**
-           * HOME = 1;
-           */
-          public static final int HOME_VALUE = 1;
-          /**
-           * MOBILE = 2;
-           */
-          public static final int MOBILE_VALUE = 2;
-          /**
-           * WORK = 3;
-           */
-          public static final int WORK_VALUE = 3;
-          /**
-           * CUSTOM = 4;
-           */
-          public static final int CUSTOM_VALUE = 4;
-
-
-          public final int getNumber() { return value; }
-
-          public static Type valueOf(int value) {
-            switch (value) {
-              case 1: return HOME;
-              case 2: return MOBILE;
-              case 3: return WORK;
-              case 4: return CUSTOM;
-              default: return null;
-            }
-          }
-
-          public static com.google.protobuf.Internal.EnumLiteMap
-              internalGetValueMap() {
-            return internalValueMap;
-          }
-          private static com.google.protobuf.Internal.EnumLiteMap
-              internalValueMap =
-                new com.google.protobuf.Internal.EnumLiteMap() {
-                  public Type findValueByNumber(int number) {
-                    return Type.valueOf(number);
-                  }
-                };
-
-          public final com.google.protobuf.Descriptors.EnumValueDescriptor
-              getValueDescriptor() {
-            return getDescriptor().getValues().get(index);
-          }
-          public final com.google.protobuf.Descriptors.EnumDescriptor
-              getDescriptorForType() {
-            return getDescriptor();
-          }
-          public static final com.google.protobuf.Descriptors.EnumDescriptor
-              getDescriptor() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.getDescriptor().getEnumTypes().get(0);
-          }
-
-          private static final Type[] VALUES = values();
-
-          public static Type valueOf(
-              com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
-            if (desc.getType() != getDescriptor()) {
-              throw new java.lang.IllegalArgumentException(
-                "EnumValueDescriptor is not for this type.");
-            }
-            return VALUES[desc.getIndex()];
-          }
-
-          private final int index;
-          private final int value;
-
-          private Type(int index, int value) {
-            this.index = index;
-            this.value = value;
-          }
-
-          // @@protoc_insertion_point(enum_scope:signalservice.DataMessage.Contact.Phone.Type)
-        }
-
-        private int bitField0_;
-        // optional string value = 1;
-        public static final int VALUE_FIELD_NUMBER = 1;
-        private java.lang.Object value_;
-        /**
-         * optional string value = 1;
-         */
-        public boolean hasValue() {
-          return ((bitField0_ & 0x00000001) == 0x00000001);
-        }
-        /**
-         * optional string value = 1;
-         */
-        public java.lang.String getValue() {
-          java.lang.Object ref = value_;
-          if (ref instanceof java.lang.String) {
-            return (java.lang.String) ref;
-          } else {
-            com.google.protobuf.ByteString bs = 
-                (com.google.protobuf.ByteString) ref;
-            java.lang.String s = bs.toStringUtf8();
-            if (bs.isValidUtf8()) {
-              value_ = s;
-            }
-            return s;
-          }
-        }
-        /**
-         * optional string value = 1;
-         */
-        public com.google.protobuf.ByteString
-            getValueBytes() {
-          java.lang.Object ref = value_;
-          if (ref instanceof java.lang.String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            value_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-
-        // optional .signalservice.DataMessage.Contact.Phone.Type type = 2;
-        public static final int TYPE_FIELD_NUMBER = 2;
-        private org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Type type_;
-        /**
-         * optional .signalservice.DataMessage.Contact.Phone.Type type = 2;
-         */
-        public boolean hasType() {
-          return ((bitField0_ & 0x00000002) == 0x00000002);
-        }
-        /**
-         * optional .signalservice.DataMessage.Contact.Phone.Type type = 2;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Type getType() {
-          return type_;
-        }
-
-        // optional string label = 3;
-        public static final int LABEL_FIELD_NUMBER = 3;
-        private java.lang.Object label_;
-        /**
-         * optional string label = 3;
-         */
-        public boolean hasLabel() {
-          return ((bitField0_ & 0x00000004) == 0x00000004);
-        }
-        /**
-         * optional string label = 3;
-         */
-        public java.lang.String getLabel() {
-          java.lang.Object ref = label_;
-          if (ref instanceof java.lang.String) {
-            return (java.lang.String) ref;
-          } else {
-            com.google.protobuf.ByteString bs = 
-                (com.google.protobuf.ByteString) ref;
-            java.lang.String s = bs.toStringUtf8();
-            if (bs.isValidUtf8()) {
-              label_ = s;
-            }
-            return s;
-          }
-        }
-        /**
-         * optional string label = 3;
-         */
-        public com.google.protobuf.ByteString
-            getLabelBytes() {
-          java.lang.Object ref = label_;
-          if (ref instanceof java.lang.String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            label_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-
-        private void initFields() {
-          value_ = "";
-          type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Type.HOME;
-          label_ = "";
-        }
-        private byte memoizedIsInitialized = -1;
-        public final boolean isInitialized() {
-          byte isInitialized = memoizedIsInitialized;
-          if (isInitialized != -1) return isInitialized == 1;
-
-          memoizedIsInitialized = 1;
-          return true;
-        }
-
-        public void writeTo(com.google.protobuf.CodedOutputStream output)
-                            throws java.io.IOException {
-          getSerializedSize();
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
-            output.writeBytes(1, getValueBytes());
-          }
-          if (((bitField0_ & 0x00000002) == 0x00000002)) {
-            output.writeEnum(2, type_.getNumber());
-          }
-          if (((bitField0_ & 0x00000004) == 0x00000004)) {
-            output.writeBytes(3, getLabelBytes());
-          }
-          getUnknownFields().writeTo(output);
-        }
-
-        private int memoizedSerializedSize = -1;
-        public int getSerializedSize() {
-          int size = memoizedSerializedSize;
-          if (size != -1) return size;
-
-          size = 0;
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeBytesSize(1, getValueBytes());
-          }
-          if (((bitField0_ & 0x00000002) == 0x00000002)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeEnumSize(2, type_.getNumber());
-          }
-          if (((bitField0_ & 0x00000004) == 0x00000004)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeBytesSize(3, getLabelBytes());
-          }
-          size += getUnknownFields().getSerializedSize();
-          memoizedSerializedSize = size;
-          return size;
-        }
-
-        private static final long serialVersionUID = 0L;
-        @java.lang.Override
-        protected java.lang.Object writeReplace()
-            throws java.io.ObjectStreamException {
-          return super.writeReplace();
-        }
-
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone parseFrom(
-            com.google.protobuf.ByteString data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return PARSER.parseFrom(data);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone parseFrom(
-            com.google.protobuf.ByteString data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return PARSER.parseFrom(data, extensionRegistry);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone parseFrom(byte[] data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return PARSER.parseFrom(data);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone parseFrom(
-            byte[] data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return PARSER.parseFrom(data, extensionRegistry);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone parseFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return PARSER.parseFrom(input);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone parseFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return PARSER.parseFrom(input, extensionRegistry);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone parseDelimitedFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return PARSER.parseDelimitedFrom(input);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone parseDelimitedFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return PARSER.parseDelimitedFrom(input, extensionRegistry);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone parseFrom(
-            com.google.protobuf.CodedInputStream input)
-            throws java.io.IOException {
-          return PARSER.parseFrom(input);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone parseFrom(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return PARSER.parseFrom(input, extensionRegistry);
-        }
-
-        public static Builder newBuilder() { return Builder.create(); }
-        public Builder newBuilderForType() { return newBuilder(); }
-        public static Builder newBuilder(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone prototype) {
-          return newBuilder().mergeFrom(prototype);
-        }
-        public Builder toBuilder() { return newBuilder(this); }
-
-        @java.lang.Override
-        protected Builder newBuilderForType(
-            com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-          Builder builder = new Builder(parent);
-          return builder;
-        }
-        /**
-         * Protobuf type {@code signalservice.DataMessage.Contact.Phone}
-         */
-        public static final class Builder extends
-            com.google.protobuf.GeneratedMessage.Builder
-           implements org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PhoneOrBuilder {
-          public static final com.google.protobuf.Descriptors.Descriptor
-              getDescriptor() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_Phone_descriptor;
-          }
-
-          protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-              internalGetFieldAccessorTable() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_Phone_fieldAccessorTable
-                .ensureFieldAccessorsInitialized(
-                    org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.class, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Builder.class);
-          }
-
-          // Construct using org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.newBuilder()
-          private Builder() {
-            maybeForceBuilderInitialization();
-          }
-
-          private Builder(
-              com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-            super(parent);
-            maybeForceBuilderInitialization();
-          }
-          private void maybeForceBuilderInitialization() {
-            if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-            }
-          }
-          private static Builder create() {
-            return new Builder();
-          }
-
-          public Builder clear() {
-            super.clear();
-            value_ = "";
-            bitField0_ = (bitField0_ & ~0x00000001);
-            type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Type.HOME;
-            bitField0_ = (bitField0_ & ~0x00000002);
-            label_ = "";
-            bitField0_ = (bitField0_ & ~0x00000004);
-            return this;
-          }
-
-          public Builder clone() {
-            return create().mergeFrom(buildPartial());
-          }
-
-          public com.google.protobuf.Descriptors.Descriptor
-              getDescriptorForType() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_Phone_descriptor;
-          }
-
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone getDefaultInstanceForType() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.getDefaultInstance();
-          }
-
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone build() {
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone result = buildPartial();
-            if (!result.isInitialized()) {
-              throw newUninitializedMessageException(result);
-            }
-            return result;
-          }
-
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone buildPartial() {
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone result = new org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone(this);
-            int from_bitField0_ = bitField0_;
-            int to_bitField0_ = 0;
-            if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-              to_bitField0_ |= 0x00000001;
-            }
-            result.value_ = value_;
-            if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
-              to_bitField0_ |= 0x00000002;
-            }
-            result.type_ = type_;
-            if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
-              to_bitField0_ |= 0x00000004;
-            }
-            result.label_ = label_;
-            result.bitField0_ = to_bitField0_;
-            onBuilt();
-            return result;
-          }
-
-          public Builder mergeFrom(com.google.protobuf.Message other) {
-            if (other instanceof org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone) {
-              return mergeFrom((org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone)other);
-            } else {
-              super.mergeFrom(other);
-              return this;
-            }
-          }
-
-          public Builder mergeFrom(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone other) {
-            if (other == org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.getDefaultInstance()) return this;
-            if (other.hasValue()) {
-              bitField0_ |= 0x00000001;
-              value_ = other.value_;
-              onChanged();
-            }
-            if (other.hasType()) {
-              setType(other.getType());
-            }
-            if (other.hasLabel()) {
-              bitField0_ |= 0x00000004;
-              label_ = other.label_;
-              onChanged();
-            }
-            this.mergeUnknownFields(other.getUnknownFields());
-            return this;
-          }
-
-          public final boolean isInitialized() {
-            return true;
-          }
-
-          public Builder mergeFrom(
-              com.google.protobuf.CodedInputStream input,
-              com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-              throws java.io.IOException {
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone parsedMessage = null;
-            try {
-              parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-            } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-              parsedMessage = (org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone) e.getUnfinishedMessage();
-              throw e;
-            } finally {
-              if (parsedMessage != null) {
-                mergeFrom(parsedMessage);
-              }
-            }
-            return this;
-          }
-          private int bitField0_;
-
-          // optional string value = 1;
-          private java.lang.Object value_ = "";
-          /**
-           * optional string value = 1;
-           */
-          public boolean hasValue() {
-            return ((bitField0_ & 0x00000001) == 0x00000001);
-          }
-          /**
-           * optional string value = 1;
-           */
-          public java.lang.String getValue() {
-            java.lang.Object ref = value_;
-            if (!(ref instanceof java.lang.String)) {
-              java.lang.String s = ((com.google.protobuf.ByteString) ref)
-                  .toStringUtf8();
-              value_ = s;
-              return s;
-            } else {
-              return (java.lang.String) ref;
-            }
-          }
-          /**
-           * optional string value = 1;
-           */
-          public com.google.protobuf.ByteString
-              getValueBytes() {
-            java.lang.Object ref = value_;
-            if (ref instanceof String) {
-              com.google.protobuf.ByteString b = 
-                  com.google.protobuf.ByteString.copyFromUtf8(
-                      (java.lang.String) ref);
-              value_ = b;
-              return b;
-            } else {
-              return (com.google.protobuf.ByteString) ref;
-            }
-          }
-          /**
-           * optional string value = 1;
-           */
-          public Builder setValue(
-              java.lang.String value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000001;
-            value_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string value = 1;
-           */
-          public Builder clearValue() {
-            bitField0_ = (bitField0_ & ~0x00000001);
-            value_ = getDefaultInstance().getValue();
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string value = 1;
-           */
-          public Builder setValueBytes(
-              com.google.protobuf.ByteString value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000001;
-            value_ = value;
-            onChanged();
-            return this;
-          }
-
-          // optional .signalservice.DataMessage.Contact.Phone.Type type = 2;
-          private org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Type type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Type.HOME;
-          /**
-           * optional .signalservice.DataMessage.Contact.Phone.Type type = 2;
-           */
-          public boolean hasType() {
-            return ((bitField0_ & 0x00000002) == 0x00000002);
-          }
-          /**
-           * optional .signalservice.DataMessage.Contact.Phone.Type type = 2;
-           */
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Type getType() {
-            return type_;
-          }
-          /**
-           * optional .signalservice.DataMessage.Contact.Phone.Type type = 2;
-           */
-          public Builder setType(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Type value) {
-            if (value == null) {
-              throw new NullPointerException();
-            }
-            bitField0_ |= 0x00000002;
-            type_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional .signalservice.DataMessage.Contact.Phone.Type type = 2;
-           */
-          public Builder clearType() {
-            bitField0_ = (bitField0_ & ~0x00000002);
-            type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Type.HOME;
-            onChanged();
-            return this;
-          }
-
-          // optional string label = 3;
-          private java.lang.Object label_ = "";
-          /**
-           * optional string label = 3;
-           */
-          public boolean hasLabel() {
-            return ((bitField0_ & 0x00000004) == 0x00000004);
-          }
-          /**
-           * optional string label = 3;
-           */
-          public java.lang.String getLabel() {
-            java.lang.Object ref = label_;
-            if (!(ref instanceof java.lang.String)) {
-              java.lang.String s = ((com.google.protobuf.ByteString) ref)
-                  .toStringUtf8();
-              label_ = s;
-              return s;
-            } else {
-              return (java.lang.String) ref;
-            }
-          }
-          /**
-           * optional string label = 3;
-           */
-          public com.google.protobuf.ByteString
-              getLabelBytes() {
-            java.lang.Object ref = label_;
-            if (ref instanceof String) {
-              com.google.protobuf.ByteString b = 
-                  com.google.protobuf.ByteString.copyFromUtf8(
-                      (java.lang.String) ref);
-              label_ = b;
-              return b;
-            } else {
-              return (com.google.protobuf.ByteString) ref;
-            }
-          }
-          /**
-           * optional string label = 3;
-           */
-          public Builder setLabel(
-              java.lang.String value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000004;
-            label_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string label = 3;
-           */
-          public Builder clearLabel() {
-            bitField0_ = (bitField0_ & ~0x00000004);
-            label_ = getDefaultInstance().getLabel();
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string label = 3;
-           */
-          public Builder setLabelBytes(
-              com.google.protobuf.ByteString value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000004;
-            label_ = value;
-            onChanged();
-            return this;
-          }
-
-          // @@protoc_insertion_point(builder_scope:signalservice.DataMessage.Contact.Phone)
-        }
-
-        static {
-          defaultInstance = new Phone(true);
-          defaultInstance.initFields();
-        }
-
-        // @@protoc_insertion_point(class_scope:signalservice.DataMessage.Contact.Phone)
-      }
-
-      public interface EmailOrBuilder
-          extends com.google.protobuf.MessageOrBuilder {
-
-        // optional string value = 1;
-        /**
-         * optional string value = 1;
-         */
-        boolean hasValue();
-        /**
-         * optional string value = 1;
-         */
-        java.lang.String getValue();
-        /**
-         * optional string value = 1;
-         */
-        com.google.protobuf.ByteString
-            getValueBytes();
-
-        // optional .signalservice.DataMessage.Contact.Email.Type type = 2;
-        /**
-         * optional .signalservice.DataMessage.Contact.Email.Type type = 2;
-         */
-        boolean hasType();
-        /**
-         * optional .signalservice.DataMessage.Contact.Email.Type type = 2;
-         */
-        org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Type getType();
-
-        // optional string label = 3;
-        /**
-         * optional string label = 3;
-         */
-        boolean hasLabel();
-        /**
-         * optional string label = 3;
-         */
-        java.lang.String getLabel();
-        /**
-         * optional string label = 3;
-         */
-        com.google.protobuf.ByteString
-            getLabelBytes();
-      }
-      /**
-       * Protobuf type {@code signalservice.DataMessage.Contact.Email}
-       */
-      public static final class Email extends
-          com.google.protobuf.GeneratedMessage
-          implements EmailOrBuilder {
-        // Use Email.newBuilder() to construct.
-        private Email(com.google.protobuf.GeneratedMessage.Builder builder) {
-          super(builder);
-          this.unknownFields = builder.getUnknownFields();
-        }
-        private Email(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-        private static final Email defaultInstance;
-        public static Email getDefaultInstance() {
-          return defaultInstance;
-        }
-
-        public Email getDefaultInstanceForType() {
-          return defaultInstance;
-        }
-
-        private final com.google.protobuf.UnknownFieldSet unknownFields;
-        @java.lang.Override
-        public final com.google.protobuf.UnknownFieldSet
-            getUnknownFields() {
-          return this.unknownFields;
-        }
-        private Email(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          initFields();
-          int mutable_bitField0_ = 0;
-          com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-              com.google.protobuf.UnknownFieldSet.newBuilder();
-          try {
-            boolean done = false;
-            while (!done) {
-              int tag = input.readTag();
-              switch (tag) {
-                case 0:
-                  done = true;
-                  break;
-                default: {
-                  if (!parseUnknownField(input, unknownFields,
-                                         extensionRegistry, tag)) {
-                    done = true;
-                  }
-                  break;
-                }
-                case 10: {
-                  bitField0_ |= 0x00000001;
-                  value_ = input.readBytes();
-                  break;
-                }
-                case 16: {
-                  int rawValue = input.readEnum();
-                  org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Type value = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Type.valueOf(rawValue);
-                  if (value == null) {
-                    unknownFields.mergeVarintField(2, rawValue);
-                  } else {
-                    bitField0_ |= 0x00000002;
-                    type_ = value;
-                  }
-                  break;
-                }
-                case 26: {
-                  bitField0_ |= 0x00000004;
-                  label_ = input.readBytes();
-                  break;
-                }
-              }
-            }
-          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-            throw e.setUnfinishedMessage(this);
-          } catch (java.io.IOException e) {
-            throw new com.google.protobuf.InvalidProtocolBufferException(
-                e.getMessage()).setUnfinishedMessage(this);
-          } finally {
-            this.unknownFields = unknownFields.build();
-            makeExtensionsImmutable();
-          }
-        }
-        public static final com.google.protobuf.Descriptors.Descriptor
-            getDescriptor() {
-          return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_Email_descriptor;
-        }
-
-        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-            internalGetFieldAccessorTable() {
-          return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_Email_fieldAccessorTable
-              .ensureFieldAccessorsInitialized(
-                  org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.class, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Builder.class);
-        }
-
-        public static com.google.protobuf.Parser PARSER =
-            new com.google.protobuf.AbstractParser() {
-          public Email parsePartialFrom(
-              com.google.protobuf.CodedInputStream input,
-              com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-              throws com.google.protobuf.InvalidProtocolBufferException {
-            return new Email(input, extensionRegistry);
-          }
-        };
-
-        @java.lang.Override
-        public com.google.protobuf.Parser getParserForType() {
-          return PARSER;
-        }
-
-        /**
-         * Protobuf enum {@code signalservice.DataMessage.Contact.Email.Type}
-         */
-        public enum Type
-            implements com.google.protobuf.ProtocolMessageEnum {
-          /**
-           * HOME = 1;
-           */
-          HOME(0, 1),
-          /**
-           * MOBILE = 2;
-           */
-          MOBILE(1, 2),
-          /**
-           * WORK = 3;
-           */
-          WORK(2, 3),
-          /**
-           * CUSTOM = 4;
-           */
-          CUSTOM(3, 4),
-          ;
-
-          /**
-           * HOME = 1;
-           */
-          public static final int HOME_VALUE = 1;
-          /**
-           * MOBILE = 2;
-           */
-          public static final int MOBILE_VALUE = 2;
-          /**
-           * WORK = 3;
-           */
-          public static final int WORK_VALUE = 3;
-          /**
-           * CUSTOM = 4;
-           */
-          public static final int CUSTOM_VALUE = 4;
-
-
-          public final int getNumber() { return value; }
-
-          public static Type valueOf(int value) {
-            switch (value) {
-              case 1: return HOME;
-              case 2: return MOBILE;
-              case 3: return WORK;
-              case 4: return CUSTOM;
-              default: return null;
-            }
-          }
-
-          public static com.google.protobuf.Internal.EnumLiteMap
-              internalGetValueMap() {
-            return internalValueMap;
-          }
-          private static com.google.protobuf.Internal.EnumLiteMap
-              internalValueMap =
-                new com.google.protobuf.Internal.EnumLiteMap() {
-                  public Type findValueByNumber(int number) {
-                    return Type.valueOf(number);
-                  }
-                };
-
-          public final com.google.protobuf.Descriptors.EnumValueDescriptor
-              getValueDescriptor() {
-            return getDescriptor().getValues().get(index);
-          }
-          public final com.google.protobuf.Descriptors.EnumDescriptor
-              getDescriptorForType() {
-            return getDescriptor();
-          }
-          public static final com.google.protobuf.Descriptors.EnumDescriptor
-              getDescriptor() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.getDescriptor().getEnumTypes().get(0);
-          }
-
-          private static final Type[] VALUES = values();
-
-          public static Type valueOf(
-              com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
-            if (desc.getType() != getDescriptor()) {
-              throw new java.lang.IllegalArgumentException(
-                "EnumValueDescriptor is not for this type.");
-            }
-            return VALUES[desc.getIndex()];
-          }
-
-          private final int index;
-          private final int value;
-
-          private Type(int index, int value) {
-            this.index = index;
-            this.value = value;
-          }
-
-          // @@protoc_insertion_point(enum_scope:signalservice.DataMessage.Contact.Email.Type)
-        }
-
-        private int bitField0_;
-        // optional string value = 1;
-        public static final int VALUE_FIELD_NUMBER = 1;
-        private java.lang.Object value_;
-        /**
-         * optional string value = 1;
-         */
-        public boolean hasValue() {
-          return ((bitField0_ & 0x00000001) == 0x00000001);
-        }
-        /**
-         * optional string value = 1;
-         */
-        public java.lang.String getValue() {
-          java.lang.Object ref = value_;
-          if (ref instanceof java.lang.String) {
-            return (java.lang.String) ref;
-          } else {
-            com.google.protobuf.ByteString bs = 
-                (com.google.protobuf.ByteString) ref;
-            java.lang.String s = bs.toStringUtf8();
-            if (bs.isValidUtf8()) {
-              value_ = s;
-            }
-            return s;
-          }
-        }
-        /**
-         * optional string value = 1;
-         */
-        public com.google.protobuf.ByteString
-            getValueBytes() {
-          java.lang.Object ref = value_;
-          if (ref instanceof java.lang.String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            value_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-
-        // optional .signalservice.DataMessage.Contact.Email.Type type = 2;
-        public static final int TYPE_FIELD_NUMBER = 2;
-        private org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Type type_;
-        /**
-         * optional .signalservice.DataMessage.Contact.Email.Type type = 2;
-         */
-        public boolean hasType() {
-          return ((bitField0_ & 0x00000002) == 0x00000002);
-        }
-        /**
-         * optional .signalservice.DataMessage.Contact.Email.Type type = 2;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Type getType() {
-          return type_;
-        }
-
-        // optional string label = 3;
-        public static final int LABEL_FIELD_NUMBER = 3;
-        private java.lang.Object label_;
-        /**
-         * optional string label = 3;
-         */
-        public boolean hasLabel() {
-          return ((bitField0_ & 0x00000004) == 0x00000004);
-        }
-        /**
-         * optional string label = 3;
-         */
-        public java.lang.String getLabel() {
-          java.lang.Object ref = label_;
-          if (ref instanceof java.lang.String) {
-            return (java.lang.String) ref;
-          } else {
-            com.google.protobuf.ByteString bs = 
-                (com.google.protobuf.ByteString) ref;
-            java.lang.String s = bs.toStringUtf8();
-            if (bs.isValidUtf8()) {
-              label_ = s;
-            }
-            return s;
-          }
-        }
-        /**
-         * optional string label = 3;
-         */
-        public com.google.protobuf.ByteString
-            getLabelBytes() {
-          java.lang.Object ref = label_;
-          if (ref instanceof java.lang.String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            label_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-
-        private void initFields() {
-          value_ = "";
-          type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Type.HOME;
-          label_ = "";
-        }
-        private byte memoizedIsInitialized = -1;
-        public final boolean isInitialized() {
-          byte isInitialized = memoizedIsInitialized;
-          if (isInitialized != -1) return isInitialized == 1;
-
-          memoizedIsInitialized = 1;
-          return true;
-        }
-
-        public void writeTo(com.google.protobuf.CodedOutputStream output)
-                            throws java.io.IOException {
-          getSerializedSize();
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
-            output.writeBytes(1, getValueBytes());
-          }
-          if (((bitField0_ & 0x00000002) == 0x00000002)) {
-            output.writeEnum(2, type_.getNumber());
-          }
-          if (((bitField0_ & 0x00000004) == 0x00000004)) {
-            output.writeBytes(3, getLabelBytes());
-          }
-          getUnknownFields().writeTo(output);
-        }
-
-        private int memoizedSerializedSize = -1;
-        public int getSerializedSize() {
-          int size = memoizedSerializedSize;
-          if (size != -1) return size;
-
-          size = 0;
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeBytesSize(1, getValueBytes());
-          }
-          if (((bitField0_ & 0x00000002) == 0x00000002)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeEnumSize(2, type_.getNumber());
-          }
-          if (((bitField0_ & 0x00000004) == 0x00000004)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeBytesSize(3, getLabelBytes());
-          }
-          size += getUnknownFields().getSerializedSize();
-          memoizedSerializedSize = size;
-          return size;
-        }
-
-        private static final long serialVersionUID = 0L;
-        @java.lang.Override
-        protected java.lang.Object writeReplace()
-            throws java.io.ObjectStreamException {
-          return super.writeReplace();
-        }
-
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email parseFrom(
-            com.google.protobuf.ByteString data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return PARSER.parseFrom(data);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email parseFrom(
-            com.google.protobuf.ByteString data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return PARSER.parseFrom(data, extensionRegistry);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email parseFrom(byte[] data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return PARSER.parseFrom(data);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email parseFrom(
-            byte[] data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return PARSER.parseFrom(data, extensionRegistry);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email parseFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return PARSER.parseFrom(input);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email parseFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return PARSER.parseFrom(input, extensionRegistry);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email parseDelimitedFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return PARSER.parseDelimitedFrom(input);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email parseDelimitedFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return PARSER.parseDelimitedFrom(input, extensionRegistry);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email parseFrom(
-            com.google.protobuf.CodedInputStream input)
-            throws java.io.IOException {
-          return PARSER.parseFrom(input);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email parseFrom(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return PARSER.parseFrom(input, extensionRegistry);
-        }
-
-        public static Builder newBuilder() { return Builder.create(); }
-        public Builder newBuilderForType() { return newBuilder(); }
-        public static Builder newBuilder(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email prototype) {
-          return newBuilder().mergeFrom(prototype);
-        }
-        public Builder toBuilder() { return newBuilder(this); }
-
-        @java.lang.Override
-        protected Builder newBuilderForType(
-            com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-          Builder builder = new Builder(parent);
-          return builder;
-        }
-        /**
-         * Protobuf type {@code signalservice.DataMessage.Contact.Email}
-         */
-        public static final class Builder extends
-            com.google.protobuf.GeneratedMessage.Builder
-           implements org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.EmailOrBuilder {
-          public static final com.google.protobuf.Descriptors.Descriptor
-              getDescriptor() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_Email_descriptor;
-          }
-
-          protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-              internalGetFieldAccessorTable() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_Email_fieldAccessorTable
-                .ensureFieldAccessorsInitialized(
-                    org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.class, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Builder.class);
-          }
-
-          // Construct using org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.newBuilder()
-          private Builder() {
-            maybeForceBuilderInitialization();
-          }
-
-          private Builder(
-              com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-            super(parent);
-            maybeForceBuilderInitialization();
-          }
-          private void maybeForceBuilderInitialization() {
-            if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-            }
-          }
-          private static Builder create() {
-            return new Builder();
-          }
-
-          public Builder clear() {
-            super.clear();
-            value_ = "";
-            bitField0_ = (bitField0_ & ~0x00000001);
-            type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Type.HOME;
-            bitField0_ = (bitField0_ & ~0x00000002);
-            label_ = "";
-            bitField0_ = (bitField0_ & ~0x00000004);
-            return this;
-          }
-
-          public Builder clone() {
-            return create().mergeFrom(buildPartial());
-          }
-
-          public com.google.protobuf.Descriptors.Descriptor
-              getDescriptorForType() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_Email_descriptor;
-          }
-
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email getDefaultInstanceForType() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.getDefaultInstance();
-          }
-
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email build() {
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email result = buildPartial();
-            if (!result.isInitialized()) {
-              throw newUninitializedMessageException(result);
-            }
-            return result;
-          }
-
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email buildPartial() {
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email result = new org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email(this);
-            int from_bitField0_ = bitField0_;
-            int to_bitField0_ = 0;
-            if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-              to_bitField0_ |= 0x00000001;
-            }
-            result.value_ = value_;
-            if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
-              to_bitField0_ |= 0x00000002;
-            }
-            result.type_ = type_;
-            if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
-              to_bitField0_ |= 0x00000004;
-            }
-            result.label_ = label_;
-            result.bitField0_ = to_bitField0_;
-            onBuilt();
-            return result;
-          }
-
-          public Builder mergeFrom(com.google.protobuf.Message other) {
-            if (other instanceof org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email) {
-              return mergeFrom((org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email)other);
-            } else {
-              super.mergeFrom(other);
-              return this;
-            }
-          }
-
-          public Builder mergeFrom(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email other) {
-            if (other == org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.getDefaultInstance()) return this;
-            if (other.hasValue()) {
-              bitField0_ |= 0x00000001;
-              value_ = other.value_;
-              onChanged();
-            }
-            if (other.hasType()) {
-              setType(other.getType());
-            }
-            if (other.hasLabel()) {
-              bitField0_ |= 0x00000004;
-              label_ = other.label_;
-              onChanged();
-            }
-            this.mergeUnknownFields(other.getUnknownFields());
-            return this;
-          }
-
-          public final boolean isInitialized() {
-            return true;
-          }
-
-          public Builder mergeFrom(
-              com.google.protobuf.CodedInputStream input,
-              com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-              throws java.io.IOException {
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email parsedMessage = null;
-            try {
-              parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-            } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-              parsedMessage = (org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email) e.getUnfinishedMessage();
-              throw e;
-            } finally {
-              if (parsedMessage != null) {
-                mergeFrom(parsedMessage);
-              }
-            }
-            return this;
-          }
-          private int bitField0_;
-
-          // optional string value = 1;
-          private java.lang.Object value_ = "";
-          /**
-           * optional string value = 1;
-           */
-          public boolean hasValue() {
-            return ((bitField0_ & 0x00000001) == 0x00000001);
-          }
-          /**
-           * optional string value = 1;
-           */
-          public java.lang.String getValue() {
-            java.lang.Object ref = value_;
-            if (!(ref instanceof java.lang.String)) {
-              java.lang.String s = ((com.google.protobuf.ByteString) ref)
-                  .toStringUtf8();
-              value_ = s;
-              return s;
-            } else {
-              return (java.lang.String) ref;
-            }
-          }
-          /**
-           * optional string value = 1;
-           */
-          public com.google.protobuf.ByteString
-              getValueBytes() {
-            java.lang.Object ref = value_;
-            if (ref instanceof String) {
-              com.google.protobuf.ByteString b = 
-                  com.google.protobuf.ByteString.copyFromUtf8(
-                      (java.lang.String) ref);
-              value_ = b;
-              return b;
-            } else {
-              return (com.google.protobuf.ByteString) ref;
-            }
-          }
-          /**
-           * optional string value = 1;
-           */
-          public Builder setValue(
-              java.lang.String value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000001;
-            value_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string value = 1;
-           */
-          public Builder clearValue() {
-            bitField0_ = (bitField0_ & ~0x00000001);
-            value_ = getDefaultInstance().getValue();
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string value = 1;
-           */
-          public Builder setValueBytes(
-              com.google.protobuf.ByteString value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000001;
-            value_ = value;
-            onChanged();
-            return this;
-          }
-
-          // optional .signalservice.DataMessage.Contact.Email.Type type = 2;
-          private org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Type type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Type.HOME;
-          /**
-           * optional .signalservice.DataMessage.Contact.Email.Type type = 2;
-           */
-          public boolean hasType() {
-            return ((bitField0_ & 0x00000002) == 0x00000002);
-          }
-          /**
-           * optional .signalservice.DataMessage.Contact.Email.Type type = 2;
-           */
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Type getType() {
-            return type_;
-          }
-          /**
-           * optional .signalservice.DataMessage.Contact.Email.Type type = 2;
-           */
-          public Builder setType(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Type value) {
-            if (value == null) {
-              throw new NullPointerException();
-            }
-            bitField0_ |= 0x00000002;
-            type_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional .signalservice.DataMessage.Contact.Email.Type type = 2;
-           */
-          public Builder clearType() {
-            bitField0_ = (bitField0_ & ~0x00000002);
-            type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Type.HOME;
-            onChanged();
-            return this;
-          }
-
-          // optional string label = 3;
-          private java.lang.Object label_ = "";
-          /**
-           * optional string label = 3;
-           */
-          public boolean hasLabel() {
-            return ((bitField0_ & 0x00000004) == 0x00000004);
-          }
-          /**
-           * optional string label = 3;
-           */
-          public java.lang.String getLabel() {
-            java.lang.Object ref = label_;
-            if (!(ref instanceof java.lang.String)) {
-              java.lang.String s = ((com.google.protobuf.ByteString) ref)
-                  .toStringUtf8();
-              label_ = s;
-              return s;
-            } else {
-              return (java.lang.String) ref;
-            }
-          }
-          /**
-           * optional string label = 3;
-           */
-          public com.google.protobuf.ByteString
-              getLabelBytes() {
-            java.lang.Object ref = label_;
-            if (ref instanceof String) {
-              com.google.protobuf.ByteString b = 
-                  com.google.protobuf.ByteString.copyFromUtf8(
-                      (java.lang.String) ref);
-              label_ = b;
-              return b;
-            } else {
-              return (com.google.protobuf.ByteString) ref;
-            }
-          }
-          /**
-           * optional string label = 3;
-           */
-          public Builder setLabel(
-              java.lang.String value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000004;
-            label_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string label = 3;
-           */
-          public Builder clearLabel() {
-            bitField0_ = (bitField0_ & ~0x00000004);
-            label_ = getDefaultInstance().getLabel();
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string label = 3;
-           */
-          public Builder setLabelBytes(
-              com.google.protobuf.ByteString value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000004;
-            label_ = value;
-            onChanged();
-            return this;
-          }
-
-          // @@protoc_insertion_point(builder_scope:signalservice.DataMessage.Contact.Email)
-        }
-
-        static {
-          defaultInstance = new Email(true);
-          defaultInstance.initFields();
-        }
-
-        // @@protoc_insertion_point(class_scope:signalservice.DataMessage.Contact.Email)
-      }
-
-      public interface PostalAddressOrBuilder
-          extends com.google.protobuf.MessageOrBuilder {
-
-        // optional .signalservice.DataMessage.Contact.PostalAddress.Type type = 1;
-        /**
-         * optional .signalservice.DataMessage.Contact.PostalAddress.Type type = 1;
-         */
-        boolean hasType();
-        /**
-         * optional .signalservice.DataMessage.Contact.PostalAddress.Type type = 1;
-         */
-        org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Type getType();
-
-        // optional string label = 2;
-        /**
-         * optional string label = 2;
-         */
-        boolean hasLabel();
-        /**
-         * optional string label = 2;
-         */
-        java.lang.String getLabel();
-        /**
-         * optional string label = 2;
-         */
-        com.google.protobuf.ByteString
-            getLabelBytes();
-
-        // optional string street = 3;
-        /**
-         * optional string street = 3;
-         */
-        boolean hasStreet();
-        /**
-         * optional string street = 3;
-         */
-        java.lang.String getStreet();
-        /**
-         * optional string street = 3;
-         */
-        com.google.protobuf.ByteString
-            getStreetBytes();
-
-        // optional string pobox = 4;
-        /**
-         * optional string pobox = 4;
-         */
-        boolean hasPobox();
-        /**
-         * optional string pobox = 4;
-         */
-        java.lang.String getPobox();
-        /**
-         * optional string pobox = 4;
-         */
-        com.google.protobuf.ByteString
-            getPoboxBytes();
-
-        // optional string neighborhood = 5;
-        /**
-         * optional string neighborhood = 5;
-         */
-        boolean hasNeighborhood();
-        /**
-         * optional string neighborhood = 5;
-         */
-        java.lang.String getNeighborhood();
-        /**
-         * optional string neighborhood = 5;
-         */
-        com.google.protobuf.ByteString
-            getNeighborhoodBytes();
-
-        // optional string city = 6;
-        /**
-         * optional string city = 6;
-         */
-        boolean hasCity();
-        /**
-         * optional string city = 6;
-         */
-        java.lang.String getCity();
-        /**
-         * optional string city = 6;
-         */
-        com.google.protobuf.ByteString
-            getCityBytes();
-
-        // optional string region = 7;
-        /**
-         * optional string region = 7;
-         */
-        boolean hasRegion();
-        /**
-         * optional string region = 7;
-         */
-        java.lang.String getRegion();
-        /**
-         * optional string region = 7;
-         */
-        com.google.protobuf.ByteString
-            getRegionBytes();
-
-        // optional string postcode = 8;
-        /**
-         * optional string postcode = 8;
-         */
-        boolean hasPostcode();
-        /**
-         * optional string postcode = 8;
-         */
-        java.lang.String getPostcode();
-        /**
-         * optional string postcode = 8;
-         */
-        com.google.protobuf.ByteString
-            getPostcodeBytes();
-
-        // optional string country = 9;
-        /**
-         * optional string country = 9;
-         */
-        boolean hasCountry();
-        /**
-         * optional string country = 9;
-         */
-        java.lang.String getCountry();
-        /**
-         * optional string country = 9;
-         */
-        com.google.protobuf.ByteString
-            getCountryBytes();
-      }
-      /**
-       * Protobuf type {@code signalservice.DataMessage.Contact.PostalAddress}
-       */
-      public static final class PostalAddress extends
-          com.google.protobuf.GeneratedMessage
-          implements PostalAddressOrBuilder {
-        // Use PostalAddress.newBuilder() to construct.
-        private PostalAddress(com.google.protobuf.GeneratedMessage.Builder builder) {
-          super(builder);
-          this.unknownFields = builder.getUnknownFields();
-        }
-        private PostalAddress(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-        private static final PostalAddress defaultInstance;
-        public static PostalAddress getDefaultInstance() {
-          return defaultInstance;
-        }
-
-        public PostalAddress getDefaultInstanceForType() {
-          return defaultInstance;
-        }
-
-        private final com.google.protobuf.UnknownFieldSet unknownFields;
-        @java.lang.Override
-        public final com.google.protobuf.UnknownFieldSet
-            getUnknownFields() {
-          return this.unknownFields;
-        }
-        private PostalAddress(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          initFields();
-          int mutable_bitField0_ = 0;
-          com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-              com.google.protobuf.UnknownFieldSet.newBuilder();
-          try {
-            boolean done = false;
-            while (!done) {
-              int tag = input.readTag();
-              switch (tag) {
-                case 0:
-                  done = true;
-                  break;
-                default: {
-                  if (!parseUnknownField(input, unknownFields,
-                                         extensionRegistry, tag)) {
-                    done = true;
-                  }
-                  break;
-                }
-                case 8: {
-                  int rawValue = input.readEnum();
-                  org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Type value = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Type.valueOf(rawValue);
-                  if (value == null) {
-                    unknownFields.mergeVarintField(1, rawValue);
-                  } else {
-                    bitField0_ |= 0x00000001;
-                    type_ = value;
-                  }
-                  break;
-                }
-                case 18: {
-                  bitField0_ |= 0x00000002;
-                  label_ = input.readBytes();
-                  break;
-                }
-                case 26: {
-                  bitField0_ |= 0x00000004;
-                  street_ = input.readBytes();
-                  break;
-                }
-                case 34: {
-                  bitField0_ |= 0x00000008;
-                  pobox_ = input.readBytes();
-                  break;
-                }
-                case 42: {
-                  bitField0_ |= 0x00000010;
-                  neighborhood_ = input.readBytes();
-                  break;
-                }
-                case 50: {
-                  bitField0_ |= 0x00000020;
-                  city_ = input.readBytes();
-                  break;
-                }
-                case 58: {
-                  bitField0_ |= 0x00000040;
-                  region_ = input.readBytes();
-                  break;
-                }
-                case 66: {
-                  bitField0_ |= 0x00000080;
-                  postcode_ = input.readBytes();
-                  break;
-                }
-                case 74: {
-                  bitField0_ |= 0x00000100;
-                  country_ = input.readBytes();
-                  break;
-                }
-              }
-            }
-          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-            throw e.setUnfinishedMessage(this);
-          } catch (java.io.IOException e) {
-            throw new com.google.protobuf.InvalidProtocolBufferException(
-                e.getMessage()).setUnfinishedMessage(this);
-          } finally {
-            this.unknownFields = unknownFields.build();
-            makeExtensionsImmutable();
-          }
-        }
-        public static final com.google.protobuf.Descriptors.Descriptor
-            getDescriptor() {
-          return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_PostalAddress_descriptor;
-        }
-
-        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-            internalGetFieldAccessorTable() {
-          return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_PostalAddress_fieldAccessorTable
-              .ensureFieldAccessorsInitialized(
-                  org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.class, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Builder.class);
-        }
-
-        public static com.google.protobuf.Parser PARSER =
-            new com.google.protobuf.AbstractParser() {
-          public PostalAddress parsePartialFrom(
-              com.google.protobuf.CodedInputStream input,
-              com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-              throws com.google.protobuf.InvalidProtocolBufferException {
-            return new PostalAddress(input, extensionRegistry);
-          }
-        };
-
-        @java.lang.Override
-        public com.google.protobuf.Parser getParserForType() {
-          return PARSER;
-        }
-
-        /**
-         * Protobuf enum {@code signalservice.DataMessage.Contact.PostalAddress.Type}
-         */
-        public enum Type
-            implements com.google.protobuf.ProtocolMessageEnum {
-          /**
-           * HOME = 1;
-           */
-          HOME(0, 1),
-          /**
-           * WORK = 2;
-           */
-          WORK(1, 2),
-          /**
-           * CUSTOM = 3;
-           */
-          CUSTOM(2, 3),
-          ;
-
-          /**
-           * HOME = 1;
-           */
-          public static final int HOME_VALUE = 1;
-          /**
-           * WORK = 2;
-           */
-          public static final int WORK_VALUE = 2;
-          /**
-           * CUSTOM = 3;
-           */
-          public static final int CUSTOM_VALUE = 3;
-
-
-          public final int getNumber() { return value; }
-
-          public static Type valueOf(int value) {
-            switch (value) {
-              case 1: return HOME;
-              case 2: return WORK;
-              case 3: return CUSTOM;
-              default: return null;
-            }
-          }
-
-          public static com.google.protobuf.Internal.EnumLiteMap
-              internalGetValueMap() {
-            return internalValueMap;
-          }
-          private static com.google.protobuf.Internal.EnumLiteMap
-              internalValueMap =
-                new com.google.protobuf.Internal.EnumLiteMap() {
-                  public Type findValueByNumber(int number) {
-                    return Type.valueOf(number);
-                  }
-                };
-
-          public final com.google.protobuf.Descriptors.EnumValueDescriptor
-              getValueDescriptor() {
-            return getDescriptor().getValues().get(index);
-          }
-          public final com.google.protobuf.Descriptors.EnumDescriptor
-              getDescriptorForType() {
-            return getDescriptor();
-          }
-          public static final com.google.protobuf.Descriptors.EnumDescriptor
-              getDescriptor() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.getDescriptor().getEnumTypes().get(0);
-          }
-
-          private static final Type[] VALUES = values();
-
-          public static Type valueOf(
-              com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
-            if (desc.getType() != getDescriptor()) {
-              throw new java.lang.IllegalArgumentException(
-                "EnumValueDescriptor is not for this type.");
-            }
-            return VALUES[desc.getIndex()];
-          }
-
-          private final int index;
-          private final int value;
-
-          private Type(int index, int value) {
-            this.index = index;
-            this.value = value;
-          }
-
-          // @@protoc_insertion_point(enum_scope:signalservice.DataMessage.Contact.PostalAddress.Type)
-        }
-
-        private int bitField0_;
-        // optional .signalservice.DataMessage.Contact.PostalAddress.Type type = 1;
-        public static final int TYPE_FIELD_NUMBER = 1;
-        private org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Type type_;
-        /**
-         * optional .signalservice.DataMessage.Contact.PostalAddress.Type type = 1;
-         */
-        public boolean hasType() {
-          return ((bitField0_ & 0x00000001) == 0x00000001);
-        }
-        /**
-         * optional .signalservice.DataMessage.Contact.PostalAddress.Type type = 1;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Type getType() {
-          return type_;
-        }
-
-        // optional string label = 2;
-        public static final int LABEL_FIELD_NUMBER = 2;
-        private java.lang.Object label_;
-        /**
-         * optional string label = 2;
-         */
-        public boolean hasLabel() {
-          return ((bitField0_ & 0x00000002) == 0x00000002);
-        }
-        /**
-         * optional string label = 2;
-         */
-        public java.lang.String getLabel() {
-          java.lang.Object ref = label_;
-          if (ref instanceof java.lang.String) {
-            return (java.lang.String) ref;
-          } else {
-            com.google.protobuf.ByteString bs = 
-                (com.google.protobuf.ByteString) ref;
-            java.lang.String s = bs.toStringUtf8();
-            if (bs.isValidUtf8()) {
-              label_ = s;
-            }
-            return s;
-          }
-        }
-        /**
-         * optional string label = 2;
-         */
-        public com.google.protobuf.ByteString
-            getLabelBytes() {
-          java.lang.Object ref = label_;
-          if (ref instanceof java.lang.String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            label_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-
-        // optional string street = 3;
-        public static final int STREET_FIELD_NUMBER = 3;
-        private java.lang.Object street_;
-        /**
-         * optional string street = 3;
-         */
-        public boolean hasStreet() {
-          return ((bitField0_ & 0x00000004) == 0x00000004);
-        }
-        /**
-         * optional string street = 3;
-         */
-        public java.lang.String getStreet() {
-          java.lang.Object ref = street_;
-          if (ref instanceof java.lang.String) {
-            return (java.lang.String) ref;
-          } else {
-            com.google.protobuf.ByteString bs = 
-                (com.google.protobuf.ByteString) ref;
-            java.lang.String s = bs.toStringUtf8();
-            if (bs.isValidUtf8()) {
-              street_ = s;
-            }
-            return s;
-          }
-        }
-        /**
-         * optional string street = 3;
-         */
-        public com.google.protobuf.ByteString
-            getStreetBytes() {
-          java.lang.Object ref = street_;
-          if (ref instanceof java.lang.String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            street_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-
-        // optional string pobox = 4;
-        public static final int POBOX_FIELD_NUMBER = 4;
-        private java.lang.Object pobox_;
-        /**
-         * optional string pobox = 4;
-         */
-        public boolean hasPobox() {
-          return ((bitField0_ & 0x00000008) == 0x00000008);
-        }
-        /**
-         * optional string pobox = 4;
-         */
-        public java.lang.String getPobox() {
-          java.lang.Object ref = pobox_;
-          if (ref instanceof java.lang.String) {
-            return (java.lang.String) ref;
-          } else {
-            com.google.protobuf.ByteString bs = 
-                (com.google.protobuf.ByteString) ref;
-            java.lang.String s = bs.toStringUtf8();
-            if (bs.isValidUtf8()) {
-              pobox_ = s;
-            }
-            return s;
-          }
-        }
-        /**
-         * optional string pobox = 4;
-         */
-        public com.google.protobuf.ByteString
-            getPoboxBytes() {
-          java.lang.Object ref = pobox_;
-          if (ref instanceof java.lang.String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            pobox_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-
-        // optional string neighborhood = 5;
-        public static final int NEIGHBORHOOD_FIELD_NUMBER = 5;
-        private java.lang.Object neighborhood_;
-        /**
-         * optional string neighborhood = 5;
-         */
-        public boolean hasNeighborhood() {
-          return ((bitField0_ & 0x00000010) == 0x00000010);
-        }
-        /**
-         * optional string neighborhood = 5;
-         */
-        public java.lang.String getNeighborhood() {
-          java.lang.Object ref = neighborhood_;
-          if (ref instanceof java.lang.String) {
-            return (java.lang.String) ref;
-          } else {
-            com.google.protobuf.ByteString bs = 
-                (com.google.protobuf.ByteString) ref;
-            java.lang.String s = bs.toStringUtf8();
-            if (bs.isValidUtf8()) {
-              neighborhood_ = s;
-            }
-            return s;
-          }
-        }
-        /**
-         * optional string neighborhood = 5;
-         */
-        public com.google.protobuf.ByteString
-            getNeighborhoodBytes() {
-          java.lang.Object ref = neighborhood_;
-          if (ref instanceof java.lang.String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            neighborhood_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-
-        // optional string city = 6;
-        public static final int CITY_FIELD_NUMBER = 6;
-        private java.lang.Object city_;
-        /**
-         * optional string city = 6;
-         */
-        public boolean hasCity() {
-          return ((bitField0_ & 0x00000020) == 0x00000020);
-        }
-        /**
-         * optional string city = 6;
-         */
-        public java.lang.String getCity() {
-          java.lang.Object ref = city_;
-          if (ref instanceof java.lang.String) {
-            return (java.lang.String) ref;
-          } else {
-            com.google.protobuf.ByteString bs = 
-                (com.google.protobuf.ByteString) ref;
-            java.lang.String s = bs.toStringUtf8();
-            if (bs.isValidUtf8()) {
-              city_ = s;
-            }
-            return s;
-          }
-        }
-        /**
-         * optional string city = 6;
-         */
-        public com.google.protobuf.ByteString
-            getCityBytes() {
-          java.lang.Object ref = city_;
-          if (ref instanceof java.lang.String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            city_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-
-        // optional string region = 7;
-        public static final int REGION_FIELD_NUMBER = 7;
-        private java.lang.Object region_;
-        /**
-         * optional string region = 7;
-         */
-        public boolean hasRegion() {
-          return ((bitField0_ & 0x00000040) == 0x00000040);
-        }
-        /**
-         * optional string region = 7;
-         */
-        public java.lang.String getRegion() {
-          java.lang.Object ref = region_;
-          if (ref instanceof java.lang.String) {
-            return (java.lang.String) ref;
-          } else {
-            com.google.protobuf.ByteString bs = 
-                (com.google.protobuf.ByteString) ref;
-            java.lang.String s = bs.toStringUtf8();
-            if (bs.isValidUtf8()) {
-              region_ = s;
-            }
-            return s;
-          }
-        }
-        /**
-         * optional string region = 7;
-         */
-        public com.google.protobuf.ByteString
-            getRegionBytes() {
-          java.lang.Object ref = region_;
-          if (ref instanceof java.lang.String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            region_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-
-        // optional string postcode = 8;
-        public static final int POSTCODE_FIELD_NUMBER = 8;
-        private java.lang.Object postcode_;
-        /**
-         * optional string postcode = 8;
-         */
-        public boolean hasPostcode() {
-          return ((bitField0_ & 0x00000080) == 0x00000080);
-        }
-        /**
-         * optional string postcode = 8;
-         */
-        public java.lang.String getPostcode() {
-          java.lang.Object ref = postcode_;
-          if (ref instanceof java.lang.String) {
-            return (java.lang.String) ref;
-          } else {
-            com.google.protobuf.ByteString bs = 
-                (com.google.protobuf.ByteString) ref;
-            java.lang.String s = bs.toStringUtf8();
-            if (bs.isValidUtf8()) {
-              postcode_ = s;
-            }
-            return s;
-          }
-        }
-        /**
-         * optional string postcode = 8;
-         */
-        public com.google.protobuf.ByteString
-            getPostcodeBytes() {
-          java.lang.Object ref = postcode_;
-          if (ref instanceof java.lang.String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            postcode_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-
-        // optional string country = 9;
-        public static final int COUNTRY_FIELD_NUMBER = 9;
-        private java.lang.Object country_;
-        /**
-         * optional string country = 9;
-         */
-        public boolean hasCountry() {
-          return ((bitField0_ & 0x00000100) == 0x00000100);
-        }
-        /**
-         * optional string country = 9;
-         */
-        public java.lang.String getCountry() {
-          java.lang.Object ref = country_;
-          if (ref instanceof java.lang.String) {
-            return (java.lang.String) ref;
-          } else {
-            com.google.protobuf.ByteString bs = 
-                (com.google.protobuf.ByteString) ref;
-            java.lang.String s = bs.toStringUtf8();
-            if (bs.isValidUtf8()) {
-              country_ = s;
-            }
-            return s;
-          }
-        }
-        /**
-         * optional string country = 9;
-         */
-        public com.google.protobuf.ByteString
-            getCountryBytes() {
-          java.lang.Object ref = country_;
-          if (ref instanceof java.lang.String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            country_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-
-        private void initFields() {
-          type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Type.HOME;
-          label_ = "";
-          street_ = "";
-          pobox_ = "";
-          neighborhood_ = "";
-          city_ = "";
-          region_ = "";
-          postcode_ = "";
-          country_ = "";
-        }
-        private byte memoizedIsInitialized = -1;
-        public final boolean isInitialized() {
-          byte isInitialized = memoizedIsInitialized;
-          if (isInitialized != -1) return isInitialized == 1;
-
-          memoizedIsInitialized = 1;
-          return true;
-        }
-
-        public void writeTo(com.google.protobuf.CodedOutputStream output)
-                            throws java.io.IOException {
-          getSerializedSize();
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
-            output.writeEnum(1, type_.getNumber());
-          }
-          if (((bitField0_ & 0x00000002) == 0x00000002)) {
-            output.writeBytes(2, getLabelBytes());
-          }
-          if (((bitField0_ & 0x00000004) == 0x00000004)) {
-            output.writeBytes(3, getStreetBytes());
-          }
-          if (((bitField0_ & 0x00000008) == 0x00000008)) {
-            output.writeBytes(4, getPoboxBytes());
-          }
-          if (((bitField0_ & 0x00000010) == 0x00000010)) {
-            output.writeBytes(5, getNeighborhoodBytes());
-          }
-          if (((bitField0_ & 0x00000020) == 0x00000020)) {
-            output.writeBytes(6, getCityBytes());
-          }
-          if (((bitField0_ & 0x00000040) == 0x00000040)) {
-            output.writeBytes(7, getRegionBytes());
-          }
-          if (((bitField0_ & 0x00000080) == 0x00000080)) {
-            output.writeBytes(8, getPostcodeBytes());
-          }
-          if (((bitField0_ & 0x00000100) == 0x00000100)) {
-            output.writeBytes(9, getCountryBytes());
-          }
-          getUnknownFields().writeTo(output);
-        }
-
-        private int memoizedSerializedSize = -1;
-        public int getSerializedSize() {
-          int size = memoizedSerializedSize;
-          if (size != -1) return size;
-
-          size = 0;
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeEnumSize(1, type_.getNumber());
-          }
-          if (((bitField0_ & 0x00000002) == 0x00000002)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeBytesSize(2, getLabelBytes());
-          }
-          if (((bitField0_ & 0x00000004) == 0x00000004)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeBytesSize(3, getStreetBytes());
-          }
-          if (((bitField0_ & 0x00000008) == 0x00000008)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeBytesSize(4, getPoboxBytes());
-          }
-          if (((bitField0_ & 0x00000010) == 0x00000010)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeBytesSize(5, getNeighborhoodBytes());
-          }
-          if (((bitField0_ & 0x00000020) == 0x00000020)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeBytesSize(6, getCityBytes());
-          }
-          if (((bitField0_ & 0x00000040) == 0x00000040)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeBytesSize(7, getRegionBytes());
-          }
-          if (((bitField0_ & 0x00000080) == 0x00000080)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeBytesSize(8, getPostcodeBytes());
-          }
-          if (((bitField0_ & 0x00000100) == 0x00000100)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeBytesSize(9, getCountryBytes());
-          }
-          size += getUnknownFields().getSerializedSize();
-          memoizedSerializedSize = size;
-          return size;
-        }
-
-        private static final long serialVersionUID = 0L;
-        @java.lang.Override
-        protected java.lang.Object writeReplace()
-            throws java.io.ObjectStreamException {
-          return super.writeReplace();
-        }
-
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress parseFrom(
-            com.google.protobuf.ByteString data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return PARSER.parseFrom(data);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress parseFrom(
-            com.google.protobuf.ByteString data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return PARSER.parseFrom(data, extensionRegistry);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress parseFrom(byte[] data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return PARSER.parseFrom(data);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress parseFrom(
-            byte[] data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return PARSER.parseFrom(data, extensionRegistry);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress parseFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return PARSER.parseFrom(input);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress parseFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return PARSER.parseFrom(input, extensionRegistry);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress parseDelimitedFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return PARSER.parseDelimitedFrom(input);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress parseDelimitedFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return PARSER.parseDelimitedFrom(input, extensionRegistry);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress parseFrom(
-            com.google.protobuf.CodedInputStream input)
-            throws java.io.IOException {
-          return PARSER.parseFrom(input);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress parseFrom(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return PARSER.parseFrom(input, extensionRegistry);
-        }
-
-        public static Builder newBuilder() { return Builder.create(); }
-        public Builder newBuilderForType() { return newBuilder(); }
-        public static Builder newBuilder(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress prototype) {
-          return newBuilder().mergeFrom(prototype);
-        }
-        public Builder toBuilder() { return newBuilder(this); }
-
-        @java.lang.Override
-        protected Builder newBuilderForType(
-            com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-          Builder builder = new Builder(parent);
-          return builder;
-        }
-        /**
-         * Protobuf type {@code signalservice.DataMessage.Contact.PostalAddress}
-         */
-        public static final class Builder extends
-            com.google.protobuf.GeneratedMessage.Builder
-           implements org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddressOrBuilder {
-          public static final com.google.protobuf.Descriptors.Descriptor
-              getDescriptor() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_PostalAddress_descriptor;
-          }
-
-          protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-              internalGetFieldAccessorTable() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_PostalAddress_fieldAccessorTable
-                .ensureFieldAccessorsInitialized(
-                    org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.class, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Builder.class);
-          }
-
-          // Construct using org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.newBuilder()
-          private Builder() {
-            maybeForceBuilderInitialization();
-          }
-
-          private Builder(
-              com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-            super(parent);
-            maybeForceBuilderInitialization();
-          }
-          private void maybeForceBuilderInitialization() {
-            if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-            }
-          }
-          private static Builder create() {
-            return new Builder();
-          }
-
-          public Builder clear() {
-            super.clear();
-            type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Type.HOME;
-            bitField0_ = (bitField0_ & ~0x00000001);
-            label_ = "";
-            bitField0_ = (bitField0_ & ~0x00000002);
-            street_ = "";
-            bitField0_ = (bitField0_ & ~0x00000004);
-            pobox_ = "";
-            bitField0_ = (bitField0_ & ~0x00000008);
-            neighborhood_ = "";
-            bitField0_ = (bitField0_ & ~0x00000010);
-            city_ = "";
-            bitField0_ = (bitField0_ & ~0x00000020);
-            region_ = "";
-            bitField0_ = (bitField0_ & ~0x00000040);
-            postcode_ = "";
-            bitField0_ = (bitField0_ & ~0x00000080);
-            country_ = "";
-            bitField0_ = (bitField0_ & ~0x00000100);
-            return this;
-          }
-
-          public Builder clone() {
-            return create().mergeFrom(buildPartial());
-          }
-
-          public com.google.protobuf.Descriptors.Descriptor
-              getDescriptorForType() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_PostalAddress_descriptor;
-          }
-
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress getDefaultInstanceForType() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.getDefaultInstance();
-          }
-
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress build() {
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress result = buildPartial();
-            if (!result.isInitialized()) {
-              throw newUninitializedMessageException(result);
-            }
-            return result;
-          }
-
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress buildPartial() {
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress result = new org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress(this);
-            int from_bitField0_ = bitField0_;
-            int to_bitField0_ = 0;
-            if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-              to_bitField0_ |= 0x00000001;
-            }
-            result.type_ = type_;
-            if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
-              to_bitField0_ |= 0x00000002;
-            }
-            result.label_ = label_;
-            if (((from_bitField0_ & 0x00000004) == 0x00000004)) {
-              to_bitField0_ |= 0x00000004;
-            }
-            result.street_ = street_;
-            if (((from_bitField0_ & 0x00000008) == 0x00000008)) {
-              to_bitField0_ |= 0x00000008;
-            }
-            result.pobox_ = pobox_;
-            if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
-              to_bitField0_ |= 0x00000010;
-            }
-            result.neighborhood_ = neighborhood_;
-            if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
-              to_bitField0_ |= 0x00000020;
-            }
-            result.city_ = city_;
-            if (((from_bitField0_ & 0x00000040) == 0x00000040)) {
-              to_bitField0_ |= 0x00000040;
-            }
-            result.region_ = region_;
-            if (((from_bitField0_ & 0x00000080) == 0x00000080)) {
-              to_bitField0_ |= 0x00000080;
-            }
-            result.postcode_ = postcode_;
-            if (((from_bitField0_ & 0x00000100) == 0x00000100)) {
-              to_bitField0_ |= 0x00000100;
-            }
-            result.country_ = country_;
-            result.bitField0_ = to_bitField0_;
-            onBuilt();
-            return result;
-          }
-
-          public Builder mergeFrom(com.google.protobuf.Message other) {
-            if (other instanceof org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress) {
-              return mergeFrom((org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress)other);
-            } else {
-              super.mergeFrom(other);
-              return this;
-            }
-          }
-
-          public Builder mergeFrom(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress other) {
-            if (other == org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.getDefaultInstance()) return this;
-            if (other.hasType()) {
-              setType(other.getType());
-            }
-            if (other.hasLabel()) {
-              bitField0_ |= 0x00000002;
-              label_ = other.label_;
-              onChanged();
-            }
-            if (other.hasStreet()) {
-              bitField0_ |= 0x00000004;
-              street_ = other.street_;
-              onChanged();
-            }
-            if (other.hasPobox()) {
-              bitField0_ |= 0x00000008;
-              pobox_ = other.pobox_;
-              onChanged();
-            }
-            if (other.hasNeighborhood()) {
-              bitField0_ |= 0x00000010;
-              neighborhood_ = other.neighborhood_;
-              onChanged();
-            }
-            if (other.hasCity()) {
-              bitField0_ |= 0x00000020;
-              city_ = other.city_;
-              onChanged();
-            }
-            if (other.hasRegion()) {
-              bitField0_ |= 0x00000040;
-              region_ = other.region_;
-              onChanged();
-            }
-            if (other.hasPostcode()) {
-              bitField0_ |= 0x00000080;
-              postcode_ = other.postcode_;
-              onChanged();
-            }
-            if (other.hasCountry()) {
-              bitField0_ |= 0x00000100;
-              country_ = other.country_;
-              onChanged();
-            }
-            this.mergeUnknownFields(other.getUnknownFields());
-            return this;
-          }
-
-          public final boolean isInitialized() {
-            return true;
-          }
-
-          public Builder mergeFrom(
-              com.google.protobuf.CodedInputStream input,
-              com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-              throws java.io.IOException {
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress parsedMessage = null;
-            try {
-              parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-            } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-              parsedMessage = (org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress) e.getUnfinishedMessage();
-              throw e;
-            } finally {
-              if (parsedMessage != null) {
-                mergeFrom(parsedMessage);
-              }
-            }
-            return this;
-          }
-          private int bitField0_;
-
-          // optional .signalservice.DataMessage.Contact.PostalAddress.Type type = 1;
-          private org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Type type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Type.HOME;
-          /**
-           * optional .signalservice.DataMessage.Contact.PostalAddress.Type type = 1;
-           */
-          public boolean hasType() {
-            return ((bitField0_ & 0x00000001) == 0x00000001);
-          }
-          /**
-           * optional .signalservice.DataMessage.Contact.PostalAddress.Type type = 1;
-           */
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Type getType() {
-            return type_;
-          }
-          /**
-           * optional .signalservice.DataMessage.Contact.PostalAddress.Type type = 1;
-           */
-          public Builder setType(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Type value) {
-            if (value == null) {
-              throw new NullPointerException();
-            }
-            bitField0_ |= 0x00000001;
-            type_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional .signalservice.DataMessage.Contact.PostalAddress.Type type = 1;
-           */
-          public Builder clearType() {
-            bitField0_ = (bitField0_ & ~0x00000001);
-            type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Type.HOME;
-            onChanged();
-            return this;
-          }
-
-          // optional string label = 2;
-          private java.lang.Object label_ = "";
-          /**
-           * optional string label = 2;
-           */
-          public boolean hasLabel() {
-            return ((bitField0_ & 0x00000002) == 0x00000002);
-          }
-          /**
-           * optional string label = 2;
-           */
-          public java.lang.String getLabel() {
-            java.lang.Object ref = label_;
-            if (!(ref instanceof java.lang.String)) {
-              java.lang.String s = ((com.google.protobuf.ByteString) ref)
-                  .toStringUtf8();
-              label_ = s;
-              return s;
-            } else {
-              return (java.lang.String) ref;
-            }
-          }
-          /**
-           * optional string label = 2;
-           */
-          public com.google.protobuf.ByteString
-              getLabelBytes() {
-            java.lang.Object ref = label_;
-            if (ref instanceof String) {
-              com.google.protobuf.ByteString b = 
-                  com.google.protobuf.ByteString.copyFromUtf8(
-                      (java.lang.String) ref);
-              label_ = b;
-              return b;
-            } else {
-              return (com.google.protobuf.ByteString) ref;
-            }
-          }
-          /**
-           * optional string label = 2;
-           */
-          public Builder setLabel(
-              java.lang.String value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000002;
-            label_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string label = 2;
-           */
-          public Builder clearLabel() {
-            bitField0_ = (bitField0_ & ~0x00000002);
-            label_ = getDefaultInstance().getLabel();
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string label = 2;
-           */
-          public Builder setLabelBytes(
-              com.google.protobuf.ByteString value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000002;
-            label_ = value;
-            onChanged();
-            return this;
-          }
-
-          // optional string street = 3;
-          private java.lang.Object street_ = "";
-          /**
-           * optional string street = 3;
-           */
-          public boolean hasStreet() {
-            return ((bitField0_ & 0x00000004) == 0x00000004);
-          }
-          /**
-           * optional string street = 3;
-           */
-          public java.lang.String getStreet() {
-            java.lang.Object ref = street_;
-            if (!(ref instanceof java.lang.String)) {
-              java.lang.String s = ((com.google.protobuf.ByteString) ref)
-                  .toStringUtf8();
-              street_ = s;
-              return s;
-            } else {
-              return (java.lang.String) ref;
-            }
-          }
-          /**
-           * optional string street = 3;
-           */
-          public com.google.protobuf.ByteString
-              getStreetBytes() {
-            java.lang.Object ref = street_;
-            if (ref instanceof String) {
-              com.google.protobuf.ByteString b = 
-                  com.google.protobuf.ByteString.copyFromUtf8(
-                      (java.lang.String) ref);
-              street_ = b;
-              return b;
-            } else {
-              return (com.google.protobuf.ByteString) ref;
-            }
-          }
-          /**
-           * optional string street = 3;
-           */
-          public Builder setStreet(
-              java.lang.String value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000004;
-            street_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string street = 3;
-           */
-          public Builder clearStreet() {
-            bitField0_ = (bitField0_ & ~0x00000004);
-            street_ = getDefaultInstance().getStreet();
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string street = 3;
-           */
-          public Builder setStreetBytes(
-              com.google.protobuf.ByteString value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000004;
-            street_ = value;
-            onChanged();
-            return this;
-          }
-
-          // optional string pobox = 4;
-          private java.lang.Object pobox_ = "";
-          /**
-           * optional string pobox = 4;
-           */
-          public boolean hasPobox() {
-            return ((bitField0_ & 0x00000008) == 0x00000008);
-          }
-          /**
-           * optional string pobox = 4;
-           */
-          public java.lang.String getPobox() {
-            java.lang.Object ref = pobox_;
-            if (!(ref instanceof java.lang.String)) {
-              java.lang.String s = ((com.google.protobuf.ByteString) ref)
-                  .toStringUtf8();
-              pobox_ = s;
-              return s;
-            } else {
-              return (java.lang.String) ref;
-            }
-          }
-          /**
-           * optional string pobox = 4;
-           */
-          public com.google.protobuf.ByteString
-              getPoboxBytes() {
-            java.lang.Object ref = pobox_;
-            if (ref instanceof String) {
-              com.google.protobuf.ByteString b = 
-                  com.google.protobuf.ByteString.copyFromUtf8(
-                      (java.lang.String) ref);
-              pobox_ = b;
-              return b;
-            } else {
-              return (com.google.protobuf.ByteString) ref;
-            }
-          }
-          /**
-           * optional string pobox = 4;
-           */
-          public Builder setPobox(
-              java.lang.String value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000008;
-            pobox_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string pobox = 4;
-           */
-          public Builder clearPobox() {
-            bitField0_ = (bitField0_ & ~0x00000008);
-            pobox_ = getDefaultInstance().getPobox();
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string pobox = 4;
-           */
-          public Builder setPoboxBytes(
-              com.google.protobuf.ByteString value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000008;
-            pobox_ = value;
-            onChanged();
-            return this;
-          }
-
-          // optional string neighborhood = 5;
-          private java.lang.Object neighborhood_ = "";
-          /**
-           * optional string neighborhood = 5;
-           */
-          public boolean hasNeighborhood() {
-            return ((bitField0_ & 0x00000010) == 0x00000010);
-          }
-          /**
-           * optional string neighborhood = 5;
-           */
-          public java.lang.String getNeighborhood() {
-            java.lang.Object ref = neighborhood_;
-            if (!(ref instanceof java.lang.String)) {
-              java.lang.String s = ((com.google.protobuf.ByteString) ref)
-                  .toStringUtf8();
-              neighborhood_ = s;
-              return s;
-            } else {
-              return (java.lang.String) ref;
-            }
-          }
-          /**
-           * optional string neighborhood = 5;
-           */
-          public com.google.protobuf.ByteString
-              getNeighborhoodBytes() {
-            java.lang.Object ref = neighborhood_;
-            if (ref instanceof String) {
-              com.google.protobuf.ByteString b = 
-                  com.google.protobuf.ByteString.copyFromUtf8(
-                      (java.lang.String) ref);
-              neighborhood_ = b;
-              return b;
-            } else {
-              return (com.google.protobuf.ByteString) ref;
-            }
-          }
-          /**
-           * optional string neighborhood = 5;
-           */
-          public Builder setNeighborhood(
-              java.lang.String value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000010;
-            neighborhood_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string neighborhood = 5;
-           */
-          public Builder clearNeighborhood() {
-            bitField0_ = (bitField0_ & ~0x00000010);
-            neighborhood_ = getDefaultInstance().getNeighborhood();
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string neighborhood = 5;
-           */
-          public Builder setNeighborhoodBytes(
-              com.google.protobuf.ByteString value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000010;
-            neighborhood_ = value;
-            onChanged();
-            return this;
-          }
-
-          // optional string city = 6;
-          private java.lang.Object city_ = "";
-          /**
-           * optional string city = 6;
-           */
-          public boolean hasCity() {
-            return ((bitField0_ & 0x00000020) == 0x00000020);
-          }
-          /**
-           * optional string city = 6;
-           */
-          public java.lang.String getCity() {
-            java.lang.Object ref = city_;
-            if (!(ref instanceof java.lang.String)) {
-              java.lang.String s = ((com.google.protobuf.ByteString) ref)
-                  .toStringUtf8();
-              city_ = s;
-              return s;
-            } else {
-              return (java.lang.String) ref;
-            }
-          }
-          /**
-           * optional string city = 6;
-           */
-          public com.google.protobuf.ByteString
-              getCityBytes() {
-            java.lang.Object ref = city_;
-            if (ref instanceof String) {
-              com.google.protobuf.ByteString b = 
-                  com.google.protobuf.ByteString.copyFromUtf8(
-                      (java.lang.String) ref);
-              city_ = b;
-              return b;
-            } else {
-              return (com.google.protobuf.ByteString) ref;
-            }
-          }
-          /**
-           * optional string city = 6;
-           */
-          public Builder setCity(
-              java.lang.String value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000020;
-            city_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string city = 6;
-           */
-          public Builder clearCity() {
-            bitField0_ = (bitField0_ & ~0x00000020);
-            city_ = getDefaultInstance().getCity();
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string city = 6;
-           */
-          public Builder setCityBytes(
-              com.google.protobuf.ByteString value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000020;
-            city_ = value;
-            onChanged();
-            return this;
-          }
-
-          // optional string region = 7;
-          private java.lang.Object region_ = "";
-          /**
-           * optional string region = 7;
-           */
-          public boolean hasRegion() {
-            return ((bitField0_ & 0x00000040) == 0x00000040);
-          }
-          /**
-           * optional string region = 7;
-           */
-          public java.lang.String getRegion() {
-            java.lang.Object ref = region_;
-            if (!(ref instanceof java.lang.String)) {
-              java.lang.String s = ((com.google.protobuf.ByteString) ref)
-                  .toStringUtf8();
-              region_ = s;
-              return s;
-            } else {
-              return (java.lang.String) ref;
-            }
-          }
-          /**
-           * optional string region = 7;
-           */
-          public com.google.protobuf.ByteString
-              getRegionBytes() {
-            java.lang.Object ref = region_;
-            if (ref instanceof String) {
-              com.google.protobuf.ByteString b = 
-                  com.google.protobuf.ByteString.copyFromUtf8(
-                      (java.lang.String) ref);
-              region_ = b;
-              return b;
-            } else {
-              return (com.google.protobuf.ByteString) ref;
-            }
-          }
-          /**
-           * optional string region = 7;
-           */
-          public Builder setRegion(
-              java.lang.String value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000040;
-            region_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string region = 7;
-           */
-          public Builder clearRegion() {
-            bitField0_ = (bitField0_ & ~0x00000040);
-            region_ = getDefaultInstance().getRegion();
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string region = 7;
-           */
-          public Builder setRegionBytes(
-              com.google.protobuf.ByteString value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000040;
-            region_ = value;
-            onChanged();
-            return this;
-          }
-
-          // optional string postcode = 8;
-          private java.lang.Object postcode_ = "";
-          /**
-           * optional string postcode = 8;
-           */
-          public boolean hasPostcode() {
-            return ((bitField0_ & 0x00000080) == 0x00000080);
-          }
-          /**
-           * optional string postcode = 8;
-           */
-          public java.lang.String getPostcode() {
-            java.lang.Object ref = postcode_;
-            if (!(ref instanceof java.lang.String)) {
-              java.lang.String s = ((com.google.protobuf.ByteString) ref)
-                  .toStringUtf8();
-              postcode_ = s;
-              return s;
-            } else {
-              return (java.lang.String) ref;
-            }
-          }
-          /**
-           * optional string postcode = 8;
-           */
-          public com.google.protobuf.ByteString
-              getPostcodeBytes() {
-            java.lang.Object ref = postcode_;
-            if (ref instanceof String) {
-              com.google.protobuf.ByteString b = 
-                  com.google.protobuf.ByteString.copyFromUtf8(
-                      (java.lang.String) ref);
-              postcode_ = b;
-              return b;
-            } else {
-              return (com.google.protobuf.ByteString) ref;
-            }
-          }
-          /**
-           * optional string postcode = 8;
-           */
-          public Builder setPostcode(
-              java.lang.String value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000080;
-            postcode_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string postcode = 8;
-           */
-          public Builder clearPostcode() {
-            bitField0_ = (bitField0_ & ~0x00000080);
-            postcode_ = getDefaultInstance().getPostcode();
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string postcode = 8;
-           */
-          public Builder setPostcodeBytes(
-              com.google.protobuf.ByteString value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000080;
-            postcode_ = value;
-            onChanged();
-            return this;
-          }
-
-          // optional string country = 9;
-          private java.lang.Object country_ = "";
-          /**
-           * optional string country = 9;
-           */
-          public boolean hasCountry() {
-            return ((bitField0_ & 0x00000100) == 0x00000100);
-          }
-          /**
-           * optional string country = 9;
-           */
-          public java.lang.String getCountry() {
-            java.lang.Object ref = country_;
-            if (!(ref instanceof java.lang.String)) {
-              java.lang.String s = ((com.google.protobuf.ByteString) ref)
-                  .toStringUtf8();
-              country_ = s;
-              return s;
-            } else {
-              return (java.lang.String) ref;
-            }
-          }
-          /**
-           * optional string country = 9;
-           */
-          public com.google.protobuf.ByteString
-              getCountryBytes() {
-            java.lang.Object ref = country_;
-            if (ref instanceof String) {
-              com.google.protobuf.ByteString b = 
-                  com.google.protobuf.ByteString.copyFromUtf8(
-                      (java.lang.String) ref);
-              country_ = b;
-              return b;
-            } else {
-              return (com.google.protobuf.ByteString) ref;
-            }
-          }
-          /**
-           * optional string country = 9;
-           */
-          public Builder setCountry(
-              java.lang.String value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000100;
-            country_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string country = 9;
-           */
-          public Builder clearCountry() {
-            bitField0_ = (bitField0_ & ~0x00000100);
-            country_ = getDefaultInstance().getCountry();
-            onChanged();
-            return this;
-          }
-          /**
-           * optional string country = 9;
-           */
-          public Builder setCountryBytes(
-              com.google.protobuf.ByteString value) {
-            if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000100;
-            country_ = value;
-            onChanged();
-            return this;
-          }
-
-          // @@protoc_insertion_point(builder_scope:signalservice.DataMessage.Contact.PostalAddress)
-        }
-
-        static {
-          defaultInstance = new PostalAddress(true);
-          defaultInstance.initFields();
-        }
-
-        // @@protoc_insertion_point(class_scope:signalservice.DataMessage.Contact.PostalAddress)
-      }
-
-      public interface AvatarOrBuilder
-          extends com.google.protobuf.MessageOrBuilder {
-
-        // optional .signalservice.AttachmentPointer avatar = 1;
-        /**
-         * optional .signalservice.AttachmentPointer avatar = 1;
-         */
-        boolean hasAvatar();
-        /**
-         * optional .signalservice.AttachmentPointer avatar = 1;
-         */
-        org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer getAvatar();
-        /**
-         * optional .signalservice.AttachmentPointer avatar = 1;
-         */
-        org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointerOrBuilder getAvatarOrBuilder();
-
-        // optional bool isProfile = 2;
-        /**
-         * optional bool isProfile = 2;
-         */
-        boolean hasIsProfile();
-        /**
-         * optional bool isProfile = 2;
-         */
-        boolean getIsProfile();
-      }
-      /**
-       * Protobuf type {@code signalservice.DataMessage.Contact.Avatar}
-       */
-      public static final class Avatar extends
-          com.google.protobuf.GeneratedMessage
-          implements AvatarOrBuilder {
-        // Use Avatar.newBuilder() to construct.
-        private Avatar(com.google.protobuf.GeneratedMessage.Builder builder) {
-          super(builder);
-          this.unknownFields = builder.getUnknownFields();
-        }
-        private Avatar(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
-
-        private static final Avatar defaultInstance;
-        public static Avatar getDefaultInstance() {
-          return defaultInstance;
-        }
-
-        public Avatar getDefaultInstanceForType() {
-          return defaultInstance;
-        }
-
-        private final com.google.protobuf.UnknownFieldSet unknownFields;
-        @java.lang.Override
-        public final com.google.protobuf.UnknownFieldSet
-            getUnknownFields() {
-          return this.unknownFields;
-        }
-        private Avatar(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          initFields();
-          int mutable_bitField0_ = 0;
-          com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-              com.google.protobuf.UnknownFieldSet.newBuilder();
-          try {
-            boolean done = false;
-            while (!done) {
-              int tag = input.readTag();
-              switch (tag) {
-                case 0:
-                  done = true;
-                  break;
-                default: {
-                  if (!parseUnknownField(input, unknownFields,
-                                         extensionRegistry, tag)) {
-                    done = true;
-                  }
-                  break;
-                }
-                case 10: {
-                  org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer.Builder subBuilder = null;
-                  if (((bitField0_ & 0x00000001) == 0x00000001)) {
-                    subBuilder = avatar_.toBuilder();
-                  }
-                  avatar_ = input.readMessage(org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer.PARSER, extensionRegistry);
-                  if (subBuilder != null) {
-                    subBuilder.mergeFrom(avatar_);
-                    avatar_ = subBuilder.buildPartial();
-                  }
-                  bitField0_ |= 0x00000001;
-                  break;
-                }
-                case 16: {
-                  bitField0_ |= 0x00000002;
-                  isProfile_ = input.readBool();
-                  break;
-                }
-              }
-            }
-          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-            throw e.setUnfinishedMessage(this);
-          } catch (java.io.IOException e) {
-            throw new com.google.protobuf.InvalidProtocolBufferException(
-                e.getMessage()).setUnfinishedMessage(this);
-          } finally {
-            this.unknownFields = unknownFields.build();
-            makeExtensionsImmutable();
-          }
-        }
-        public static final com.google.protobuf.Descriptors.Descriptor
-            getDescriptor() {
-          return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_Avatar_descriptor;
-        }
-
-        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-            internalGetFieldAccessorTable() {
-          return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_Avatar_fieldAccessorTable
-              .ensureFieldAccessorsInitialized(
-                  org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar.class, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar.Builder.class);
-        }
-
-        public static com.google.protobuf.Parser PARSER =
-            new com.google.protobuf.AbstractParser() {
-          public Avatar parsePartialFrom(
-              com.google.protobuf.CodedInputStream input,
-              com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-              throws com.google.protobuf.InvalidProtocolBufferException {
-            return new Avatar(input, extensionRegistry);
-          }
-        };
-
-        @java.lang.Override
-        public com.google.protobuf.Parser getParserForType() {
-          return PARSER;
-        }
-
-        private int bitField0_;
-        // optional .signalservice.AttachmentPointer avatar = 1;
-        public static final int AVATAR_FIELD_NUMBER = 1;
-        private org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer avatar_;
-        /**
-         * optional .signalservice.AttachmentPointer avatar = 1;
-         */
-        public boolean hasAvatar() {
-          return ((bitField0_ & 0x00000001) == 0x00000001);
-        }
-        /**
-         * optional .signalservice.AttachmentPointer avatar = 1;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer getAvatar() {
-          return avatar_;
-        }
-        /**
-         * optional .signalservice.AttachmentPointer avatar = 1;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointerOrBuilder getAvatarOrBuilder() {
-          return avatar_;
-        }
-
-        // optional bool isProfile = 2;
-        public static final int ISPROFILE_FIELD_NUMBER = 2;
-        private boolean isProfile_;
-        /**
-         * optional bool isProfile = 2;
-         */
-        public boolean hasIsProfile() {
-          return ((bitField0_ & 0x00000002) == 0x00000002);
-        }
-        /**
-         * optional bool isProfile = 2;
-         */
-        public boolean getIsProfile() {
-          return isProfile_;
-        }
-
-        private void initFields() {
-          avatar_ = org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer.getDefaultInstance();
-          isProfile_ = false;
-        }
-        private byte memoizedIsInitialized = -1;
-        public final boolean isInitialized() {
-          byte isInitialized = memoizedIsInitialized;
-          if (isInitialized != -1) return isInitialized == 1;
-
-          memoizedIsInitialized = 1;
-          return true;
-        }
-
-        public void writeTo(com.google.protobuf.CodedOutputStream output)
-                            throws java.io.IOException {
-          getSerializedSize();
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
-            output.writeMessage(1, avatar_);
-          }
-          if (((bitField0_ & 0x00000002) == 0x00000002)) {
-            output.writeBool(2, isProfile_);
-          }
-          getUnknownFields().writeTo(output);
-        }
-
-        private int memoizedSerializedSize = -1;
-        public int getSerializedSize() {
-          int size = memoizedSerializedSize;
-          if (size != -1) return size;
-
-          size = 0;
-          if (((bitField0_ & 0x00000001) == 0x00000001)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeMessageSize(1, avatar_);
-          }
-          if (((bitField0_ & 0x00000002) == 0x00000002)) {
-            size += com.google.protobuf.CodedOutputStream
-              .computeBoolSize(2, isProfile_);
-          }
-          size += getUnknownFields().getSerializedSize();
-          memoizedSerializedSize = size;
-          return size;
-        }
-
-        private static final long serialVersionUID = 0L;
-        @java.lang.Override
-        protected java.lang.Object writeReplace()
-            throws java.io.ObjectStreamException {
-          return super.writeReplace();
-        }
-
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar parseFrom(
-            com.google.protobuf.ByteString data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return PARSER.parseFrom(data);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar parseFrom(
-            com.google.protobuf.ByteString data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return PARSER.parseFrom(data, extensionRegistry);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar parseFrom(byte[] data)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return PARSER.parseFrom(data);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar parseFrom(
-            byte[] data,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws com.google.protobuf.InvalidProtocolBufferException {
-          return PARSER.parseFrom(data, extensionRegistry);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar parseFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return PARSER.parseFrom(input);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar parseFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return PARSER.parseFrom(input, extensionRegistry);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar parseDelimitedFrom(java.io.InputStream input)
-            throws java.io.IOException {
-          return PARSER.parseDelimitedFrom(input);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar parseDelimitedFrom(
-            java.io.InputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return PARSER.parseDelimitedFrom(input, extensionRegistry);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar parseFrom(
-            com.google.protobuf.CodedInputStream input)
-            throws java.io.IOException {
-          return PARSER.parseFrom(input);
-        }
-        public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar parseFrom(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          return PARSER.parseFrom(input, extensionRegistry);
-        }
-
-        public static Builder newBuilder() { return Builder.create(); }
-        public Builder newBuilderForType() { return newBuilder(); }
-        public static Builder newBuilder(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar prototype) {
-          return newBuilder().mergeFrom(prototype);
-        }
-        public Builder toBuilder() { return newBuilder(this); }
-
-        @java.lang.Override
-        protected Builder newBuilderForType(
-            com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-          Builder builder = new Builder(parent);
-          return builder;
-        }
-        /**
-         * Protobuf type {@code signalservice.DataMessage.Contact.Avatar}
-         */
-        public static final class Builder extends
-            com.google.protobuf.GeneratedMessage.Builder
-           implements org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.AvatarOrBuilder {
-          public static final com.google.protobuf.Descriptors.Descriptor
-              getDescriptor() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_Avatar_descriptor;
-          }
-
-          protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-              internalGetFieldAccessorTable() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_Avatar_fieldAccessorTable
-                .ensureFieldAccessorsInitialized(
-                    org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar.class, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar.Builder.class);
-          }
-
-          // Construct using org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar.newBuilder()
-          private Builder() {
-            maybeForceBuilderInitialization();
-          }
-
-          private Builder(
-              com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-            super(parent);
-            maybeForceBuilderInitialization();
-          }
-          private void maybeForceBuilderInitialization() {
-            if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-              getAvatarFieldBuilder();
-            }
-          }
-          private static Builder create() {
-            return new Builder();
-          }
-
-          public Builder clear() {
-            super.clear();
-            if (avatarBuilder_ == null) {
-              avatar_ = org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer.getDefaultInstance();
-            } else {
-              avatarBuilder_.clear();
-            }
-            bitField0_ = (bitField0_ & ~0x00000001);
-            isProfile_ = false;
-            bitField0_ = (bitField0_ & ~0x00000002);
-            return this;
-          }
-
-          public Builder clone() {
-            return create().mergeFrom(buildPartial());
-          }
-
-          public com.google.protobuf.Descriptors.Descriptor
-              getDescriptorForType() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_Avatar_descriptor;
-          }
-
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar getDefaultInstanceForType() {
-            return org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar.getDefaultInstance();
-          }
-
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar build() {
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar result = buildPartial();
-            if (!result.isInitialized()) {
-              throw newUninitializedMessageException(result);
-            }
-            return result;
-          }
-
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar buildPartial() {
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar result = new org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar(this);
-            int from_bitField0_ = bitField0_;
-            int to_bitField0_ = 0;
-            if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-              to_bitField0_ |= 0x00000001;
-            }
-            if (avatarBuilder_ == null) {
-              result.avatar_ = avatar_;
-            } else {
-              result.avatar_ = avatarBuilder_.build();
-            }
-            if (((from_bitField0_ & 0x00000002) == 0x00000002)) {
-              to_bitField0_ |= 0x00000002;
-            }
-            result.isProfile_ = isProfile_;
-            result.bitField0_ = to_bitField0_;
-            onBuilt();
-            return result;
-          }
-
-          public Builder mergeFrom(com.google.protobuf.Message other) {
-            if (other instanceof org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar) {
-              return mergeFrom((org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar)other);
-            } else {
-              super.mergeFrom(other);
-              return this;
-            }
-          }
-
-          public Builder mergeFrom(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar other) {
-            if (other == org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar.getDefaultInstance()) return this;
-            if (other.hasAvatar()) {
-              mergeAvatar(other.getAvatar());
-            }
-            if (other.hasIsProfile()) {
-              setIsProfile(other.getIsProfile());
-            }
-            this.mergeUnknownFields(other.getUnknownFields());
-            return this;
-          }
-
-          public final boolean isInitialized() {
-            return true;
-          }
-
-          public Builder mergeFrom(
-              com.google.protobuf.CodedInputStream input,
-              com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-              throws java.io.IOException {
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar parsedMessage = null;
-            try {
-              parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-            } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-              parsedMessage = (org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar) e.getUnfinishedMessage();
-              throw e;
-            } finally {
-              if (parsedMessage != null) {
-                mergeFrom(parsedMessage);
-              }
-            }
-            return this;
-          }
-          private int bitField0_;
-
-          // optional .signalservice.AttachmentPointer avatar = 1;
-          private org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer avatar_ = org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer.getDefaultInstance();
-          private com.google.protobuf.SingleFieldBuilder<
-              org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer, org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointerOrBuilder> avatarBuilder_;
-          /**
-           * optional .signalservice.AttachmentPointer avatar = 1;
-           */
-          public boolean hasAvatar() {
-            return ((bitField0_ & 0x00000001) == 0x00000001);
-          }
-          /**
-           * optional .signalservice.AttachmentPointer avatar = 1;
-           */
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer getAvatar() {
-            if (avatarBuilder_ == null) {
-              return avatar_;
-            } else {
-              return avatarBuilder_.getMessage();
-            }
-          }
-          /**
-           * optional .signalservice.AttachmentPointer avatar = 1;
-           */
-          public Builder setAvatar(org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer value) {
-            if (avatarBuilder_ == null) {
-              if (value == null) {
-                throw new NullPointerException();
-              }
-              avatar_ = value;
-              onChanged();
-            } else {
-              avatarBuilder_.setMessage(value);
-            }
-            bitField0_ |= 0x00000001;
-            return this;
-          }
-          /**
-           * optional .signalservice.AttachmentPointer avatar = 1;
-           */
-          public Builder setAvatar(
-              org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer.Builder builderForValue) {
-            if (avatarBuilder_ == null) {
-              avatar_ = builderForValue.build();
-              onChanged();
-            } else {
-              avatarBuilder_.setMessage(builderForValue.build());
-            }
-            bitField0_ |= 0x00000001;
-            return this;
-          }
-          /**
-           * optional .signalservice.AttachmentPointer avatar = 1;
-           */
-          public Builder mergeAvatar(org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer value) {
-            if (avatarBuilder_ == null) {
-              if (((bitField0_ & 0x00000001) == 0x00000001) &&
-                  avatar_ != org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer.getDefaultInstance()) {
-                avatar_ =
-                  org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer.newBuilder(avatar_).mergeFrom(value).buildPartial();
-              } else {
-                avatar_ = value;
-              }
-              onChanged();
-            } else {
-              avatarBuilder_.mergeFrom(value);
-            }
-            bitField0_ |= 0x00000001;
-            return this;
-          }
-          /**
-           * optional .signalservice.AttachmentPointer avatar = 1;
-           */
-          public Builder clearAvatar() {
-            if (avatarBuilder_ == null) {
-              avatar_ = org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer.getDefaultInstance();
-              onChanged();
-            } else {
-              avatarBuilder_.clear();
-            }
-            bitField0_ = (bitField0_ & ~0x00000001);
-            return this;
-          }
-          /**
-           * optional .signalservice.AttachmentPointer avatar = 1;
-           */
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer.Builder getAvatarBuilder() {
-            bitField0_ |= 0x00000001;
-            onChanged();
-            return getAvatarFieldBuilder().getBuilder();
-          }
-          /**
-           * optional .signalservice.AttachmentPointer avatar = 1;
-           */
-          public org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointerOrBuilder getAvatarOrBuilder() {
-            if (avatarBuilder_ != null) {
-              return avatarBuilder_.getMessageOrBuilder();
-            } else {
-              return avatar_;
-            }
-          }
-          /**
-           * optional .signalservice.AttachmentPointer avatar = 1;
-           */
-          private com.google.protobuf.SingleFieldBuilder<
-              org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer, org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointerOrBuilder> 
-              getAvatarFieldBuilder() {
-            if (avatarBuilder_ == null) {
-              avatarBuilder_ = new com.google.protobuf.SingleFieldBuilder<
-                  org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer, org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointerOrBuilder>(
-                      avatar_,
-                      getParentForChildren(),
-                      isClean());
-              avatar_ = null;
-            }
-            return avatarBuilder_;
-          }
-
-          // optional bool isProfile = 2;
-          private boolean isProfile_ ;
-          /**
-           * optional bool isProfile = 2;
-           */
-          public boolean hasIsProfile() {
-            return ((bitField0_ & 0x00000002) == 0x00000002);
-          }
-          /**
-           * optional bool isProfile = 2;
-           */
-          public boolean getIsProfile() {
-            return isProfile_;
-          }
-          /**
-           * optional bool isProfile = 2;
-           */
-          public Builder setIsProfile(boolean value) {
-            bitField0_ |= 0x00000002;
-            isProfile_ = value;
-            onChanged();
-            return this;
-          }
-          /**
-           * optional bool isProfile = 2;
-           */
-          public Builder clearIsProfile() {
-            bitField0_ = (bitField0_ & ~0x00000002);
-            isProfile_ = false;
-            onChanged();
-            return this;
-          }
-
-          // @@protoc_insertion_point(builder_scope:signalservice.DataMessage.Contact.Avatar)
-        }
-
-        static {
-          defaultInstance = new Avatar(true);
-          defaultInstance.initFields();
-        }
-
-        // @@protoc_insertion_point(class_scope:signalservice.DataMessage.Contact.Avatar)
-      }
-
-      private int bitField0_;
-      // optional .signalservice.DataMessage.Contact.Name name = 1;
-      public static final int NAME_FIELD_NUMBER = 1;
-      private org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name name_;
-      /**
-       * optional .signalservice.DataMessage.Contact.Name name = 1;
-       */
-      public boolean hasName() {
-        return ((bitField0_ & 0x00000001) == 0x00000001);
-      }
-      /**
-       * optional .signalservice.DataMessage.Contact.Name name = 1;
-       */
-      public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name getName() {
-        return name_;
-      }
-      /**
-       * optional .signalservice.DataMessage.Contact.Name name = 1;
-       */
-      public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.NameOrBuilder getNameOrBuilder() {
-        return name_;
-      }
-
-      // repeated .signalservice.DataMessage.Contact.Phone number = 3;
-      public static final int NUMBER_FIELD_NUMBER = 3;
-      private java.util.List number_;
-      /**
-       * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-       */
-      public java.util.List getNumberList() {
-        return number_;
-      }
-      /**
-       * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-       */
-      public java.util.List 
-          getNumberOrBuilderList() {
-        return number_;
-      }
-      /**
-       * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-       */
-      public int getNumberCount() {
-        return number_.size();
-      }
-      /**
-       * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-       */
-      public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone getNumber(int index) {
-        return number_.get(index);
-      }
-      /**
-       * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-       */
-      public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PhoneOrBuilder getNumberOrBuilder(
-          int index) {
-        return number_.get(index);
-      }
-
-      // repeated .signalservice.DataMessage.Contact.Email email = 4;
-      public static final int EMAIL_FIELD_NUMBER = 4;
-      private java.util.List email_;
-      /**
-       * repeated .signalservice.DataMessage.Contact.Email email = 4;
-       */
-      public java.util.List getEmailList() {
-        return email_;
-      }
-      /**
-       * repeated .signalservice.DataMessage.Contact.Email email = 4;
-       */
-      public java.util.List 
-          getEmailOrBuilderList() {
-        return email_;
-      }
-      /**
-       * repeated .signalservice.DataMessage.Contact.Email email = 4;
-       */
-      public int getEmailCount() {
-        return email_.size();
-      }
-      /**
-       * repeated .signalservice.DataMessage.Contact.Email email = 4;
-       */
-      public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email getEmail(int index) {
-        return email_.get(index);
-      }
-      /**
-       * repeated .signalservice.DataMessage.Contact.Email email = 4;
-       */
-      public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.EmailOrBuilder getEmailOrBuilder(
-          int index) {
-        return email_.get(index);
-      }
-
-      // repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-      public static final int ADDRESS_FIELD_NUMBER = 5;
-      private java.util.List address_;
-      /**
-       * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-       */
-      public java.util.List getAddressList() {
-        return address_;
-      }
-      /**
-       * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-       */
-      public java.util.List 
-          getAddressOrBuilderList() {
-        return address_;
-      }
-      /**
-       * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-       */
-      public int getAddressCount() {
-        return address_.size();
-      }
-      /**
-       * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-       */
-      public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress getAddress(int index) {
-        return address_.get(index);
-      }
-      /**
-       * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-       */
-      public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddressOrBuilder getAddressOrBuilder(
-          int index) {
-        return address_.get(index);
-      }
-
-      // optional .signalservice.DataMessage.Contact.Avatar avatar = 6;
-      public static final int AVATAR_FIELD_NUMBER = 6;
-      private org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar avatar_;
-      /**
-       * optional .signalservice.DataMessage.Contact.Avatar avatar = 6;
-       */
-      public boolean hasAvatar() {
-        return ((bitField0_ & 0x00000002) == 0x00000002);
-      }
-      /**
-       * optional .signalservice.DataMessage.Contact.Avatar avatar = 6;
-       */
-      public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar getAvatar() {
-        return avatar_;
-      }
-      /**
-       * optional .signalservice.DataMessage.Contact.Avatar avatar = 6;
-       */
-      public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.AvatarOrBuilder getAvatarOrBuilder() {
-        return avatar_;
-      }
-
-      // optional string organization = 7;
-      public static final int ORGANIZATION_FIELD_NUMBER = 7;
-      private java.lang.Object organization_;
-      /**
-       * optional string organization = 7;
-       */
-      public boolean hasOrganization() {
-        return ((bitField0_ & 0x00000004) == 0x00000004);
-      }
-      /**
-       * optional string organization = 7;
-       */
-      public java.lang.String getOrganization() {
-        java.lang.Object ref = organization_;
-        if (ref instanceof java.lang.String) {
-          return (java.lang.String) ref;
-        } else {
-          com.google.protobuf.ByteString bs = 
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          if (bs.isValidUtf8()) {
-            organization_ = s;
-          }
-          return s;
-        }
-      }
-      /**
-       * optional string organization = 7;
-       */
-      public com.google.protobuf.ByteString
-          getOrganizationBytes() {
-        java.lang.Object ref = organization_;
-        if (ref instanceof java.lang.String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          organization_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-
-      private void initFields() {
-        name_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name.getDefaultInstance();
-        number_ = java.util.Collections.emptyList();
-        email_ = java.util.Collections.emptyList();
-        address_ = java.util.Collections.emptyList();
-        avatar_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar.getDefaultInstance();
-        organization_ = "";
-      }
-      private byte memoizedIsInitialized = -1;
-      public final boolean isInitialized() {
-        byte isInitialized = memoizedIsInitialized;
-        if (isInitialized != -1) return isInitialized == 1;
-
-        memoizedIsInitialized = 1;
-        return true;
-      }
-
-      public void writeTo(com.google.protobuf.CodedOutputStream output)
-                          throws java.io.IOException {
-        getSerializedSize();
-        if (((bitField0_ & 0x00000001) == 0x00000001)) {
-          output.writeMessage(1, name_);
-        }
-        for (int i = 0; i < number_.size(); i++) {
-          output.writeMessage(3, number_.get(i));
-        }
-        for (int i = 0; i < email_.size(); i++) {
-          output.writeMessage(4, email_.get(i));
-        }
-        for (int i = 0; i < address_.size(); i++) {
-          output.writeMessage(5, address_.get(i));
-        }
-        if (((bitField0_ & 0x00000002) == 0x00000002)) {
-          output.writeMessage(6, avatar_);
-        }
-        if (((bitField0_ & 0x00000004) == 0x00000004)) {
-          output.writeBytes(7, getOrganizationBytes());
-        }
-        getUnknownFields().writeTo(output);
-      }
-
-      private int memoizedSerializedSize = -1;
-      public int getSerializedSize() {
-        int size = memoizedSerializedSize;
-        if (size != -1) return size;
-
-        size = 0;
-        if (((bitField0_ & 0x00000001) == 0x00000001)) {
-          size += com.google.protobuf.CodedOutputStream
-            .computeMessageSize(1, name_);
-        }
-        for (int i = 0; i < number_.size(); i++) {
-          size += com.google.protobuf.CodedOutputStream
-            .computeMessageSize(3, number_.get(i));
-        }
-        for (int i = 0; i < email_.size(); i++) {
-          size += com.google.protobuf.CodedOutputStream
-            .computeMessageSize(4, email_.get(i));
-        }
-        for (int i = 0; i < address_.size(); i++) {
-          size += com.google.protobuf.CodedOutputStream
-            .computeMessageSize(5, address_.get(i));
-        }
-        if (((bitField0_ & 0x00000002) == 0x00000002)) {
-          size += com.google.protobuf.CodedOutputStream
-            .computeMessageSize(6, avatar_);
-        }
-        if (((bitField0_ & 0x00000004) == 0x00000004)) {
-          size += com.google.protobuf.CodedOutputStream
-            .computeBytesSize(7, getOrganizationBytes());
-        }
-        size += getUnknownFields().getSerializedSize();
-        memoizedSerializedSize = size;
-        return size;
-      }
-
-      private static final long serialVersionUID = 0L;
-      @java.lang.Override
-      protected java.lang.Object writeReplace()
-          throws java.io.ObjectStreamException {
-        return super.writeReplace();
-      }
-
-      public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact parseFrom(
-          com.google.protobuf.ByteString data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return PARSER.parseFrom(data);
-      }
-      public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact parseFrom(
-          com.google.protobuf.ByteString data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return PARSER.parseFrom(data, extensionRegistry);
-      }
-      public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact parseFrom(byte[] data)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return PARSER.parseFrom(data);
-      }
-      public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact parseFrom(
-          byte[] data,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return PARSER.parseFrom(data, extensionRegistry);
-      }
-      public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact parseFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return PARSER.parseFrom(input);
-      }
-      public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact parseFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return PARSER.parseFrom(input, extensionRegistry);
-      }
-      public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact parseDelimitedFrom(java.io.InputStream input)
-          throws java.io.IOException {
-        return PARSER.parseDelimitedFrom(input);
-      }
-      public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact parseDelimitedFrom(
-          java.io.InputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return PARSER.parseDelimitedFrom(input, extensionRegistry);
-      }
-      public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact parseFrom(
-          com.google.protobuf.CodedInputStream input)
-          throws java.io.IOException {
-        return PARSER.parseFrom(input);
-      }
-      public static org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact parseFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        return PARSER.parseFrom(input, extensionRegistry);
-      }
-
-      public static Builder newBuilder() { return Builder.create(); }
-      public Builder newBuilderForType() { return newBuilder(); }
-      public static Builder newBuilder(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact prototype) {
-        return newBuilder().mergeFrom(prototype);
-      }
-      public Builder toBuilder() { return newBuilder(this); }
-
-      @java.lang.Override
-      protected Builder newBuilderForType(
-          com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-        Builder builder = new Builder(parent);
-        return builder;
-      }
-      /**
-       * Protobuf type {@code signalservice.DataMessage.Contact}
-       */
-      public static final class Builder extends
-          com.google.protobuf.GeneratedMessage.Builder
-         implements org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.ContactOrBuilder {
-        public static final com.google.protobuf.Descriptors.Descriptor
-            getDescriptor() {
-          return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_descriptor;
-        }
-
-        protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
-            internalGetFieldAccessorTable() {
-          return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_fieldAccessorTable
-              .ensureFieldAccessorsInitialized(
-                  org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.class, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Builder.class);
-        }
-
-        // Construct using org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.newBuilder()
-        private Builder() {
-          maybeForceBuilderInitialization();
-        }
-
-        private Builder(
-            com.google.protobuf.GeneratedMessage.BuilderParent parent) {
-          super(parent);
-          maybeForceBuilderInitialization();
-        }
-        private void maybeForceBuilderInitialization() {
-          if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) {
-            getNameFieldBuilder();
-            getNumberFieldBuilder();
-            getEmailFieldBuilder();
-            getAddressFieldBuilder();
-            getAvatarFieldBuilder();
-          }
-        }
-        private static Builder create() {
-          return new Builder();
-        }
-
-        public Builder clear() {
-          super.clear();
-          if (nameBuilder_ == null) {
-            name_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name.getDefaultInstance();
-          } else {
-            nameBuilder_.clear();
-          }
-          bitField0_ = (bitField0_ & ~0x00000001);
-          if (numberBuilder_ == null) {
-            number_ = java.util.Collections.emptyList();
-            bitField0_ = (bitField0_ & ~0x00000002);
-          } else {
-            numberBuilder_.clear();
-          }
-          if (emailBuilder_ == null) {
-            email_ = java.util.Collections.emptyList();
-            bitField0_ = (bitField0_ & ~0x00000004);
-          } else {
-            emailBuilder_.clear();
-          }
-          if (addressBuilder_ == null) {
-            address_ = java.util.Collections.emptyList();
-            bitField0_ = (bitField0_ & ~0x00000008);
-          } else {
-            addressBuilder_.clear();
-          }
-          if (avatarBuilder_ == null) {
-            avatar_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar.getDefaultInstance();
-          } else {
-            avatarBuilder_.clear();
-          }
-          bitField0_ = (bitField0_ & ~0x00000010);
-          organization_ = "";
-          bitField0_ = (bitField0_ & ~0x00000020);
-          return this;
-        }
-
-        public Builder clone() {
-          return create().mergeFrom(buildPartial());
-        }
-
-        public com.google.protobuf.Descriptors.Descriptor
-            getDescriptorForType() {
-          return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_DataMessage_Contact_descriptor;
-        }
-
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact getDefaultInstanceForType() {
-          return org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.getDefaultInstance();
-        }
-
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact build() {
-          org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact result = buildPartial();
-          if (!result.isInitialized()) {
-            throw newUninitializedMessageException(result);
-          }
-          return result;
-        }
-
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact buildPartial() {
-          org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact result = new org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact(this);
-          int from_bitField0_ = bitField0_;
-          int to_bitField0_ = 0;
-          if (((from_bitField0_ & 0x00000001) == 0x00000001)) {
-            to_bitField0_ |= 0x00000001;
-          }
-          if (nameBuilder_ == null) {
-            result.name_ = name_;
-          } else {
-            result.name_ = nameBuilder_.build();
-          }
-          if (numberBuilder_ == null) {
-            if (((bitField0_ & 0x00000002) == 0x00000002)) {
-              number_ = java.util.Collections.unmodifiableList(number_);
-              bitField0_ = (bitField0_ & ~0x00000002);
-            }
-            result.number_ = number_;
-          } else {
-            result.number_ = numberBuilder_.build();
-          }
-          if (emailBuilder_ == null) {
-            if (((bitField0_ & 0x00000004) == 0x00000004)) {
-              email_ = java.util.Collections.unmodifiableList(email_);
-              bitField0_ = (bitField0_ & ~0x00000004);
-            }
-            result.email_ = email_;
-          } else {
-            result.email_ = emailBuilder_.build();
-          }
-          if (addressBuilder_ == null) {
-            if (((bitField0_ & 0x00000008) == 0x00000008)) {
-              address_ = java.util.Collections.unmodifiableList(address_);
-              bitField0_ = (bitField0_ & ~0x00000008);
-            }
-            result.address_ = address_;
-          } else {
-            result.address_ = addressBuilder_.build();
-          }
-          if (((from_bitField0_ & 0x00000010) == 0x00000010)) {
-            to_bitField0_ |= 0x00000002;
-          }
-          if (avatarBuilder_ == null) {
-            result.avatar_ = avatar_;
-          } else {
-            result.avatar_ = avatarBuilder_.build();
-          }
-          if (((from_bitField0_ & 0x00000020) == 0x00000020)) {
-            to_bitField0_ |= 0x00000004;
-          }
-          result.organization_ = organization_;
-          result.bitField0_ = to_bitField0_;
-          onBuilt();
-          return result;
-        }
-
-        public Builder mergeFrom(com.google.protobuf.Message other) {
-          if (other instanceof org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact) {
-            return mergeFrom((org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact)other);
-          } else {
-            super.mergeFrom(other);
-            return this;
-          }
-        }
-
-        public Builder mergeFrom(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact other) {
-          if (other == org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.getDefaultInstance()) return this;
-          if (other.hasName()) {
-            mergeName(other.getName());
-          }
-          if (numberBuilder_ == null) {
-            if (!other.number_.isEmpty()) {
-              if (number_.isEmpty()) {
-                number_ = other.number_;
-                bitField0_ = (bitField0_ & ~0x00000002);
-              } else {
-                ensureNumberIsMutable();
-                number_.addAll(other.number_);
-              }
-              onChanged();
-            }
-          } else {
-            if (!other.number_.isEmpty()) {
-              if (numberBuilder_.isEmpty()) {
-                numberBuilder_.dispose();
-                numberBuilder_ = null;
-                number_ = other.number_;
-                bitField0_ = (bitField0_ & ~0x00000002);
-                numberBuilder_ = 
-                  com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
-                     getNumberFieldBuilder() : null;
-              } else {
-                numberBuilder_.addAllMessages(other.number_);
-              }
-            }
-          }
-          if (emailBuilder_ == null) {
-            if (!other.email_.isEmpty()) {
-              if (email_.isEmpty()) {
-                email_ = other.email_;
-                bitField0_ = (bitField0_ & ~0x00000004);
-              } else {
-                ensureEmailIsMutable();
-                email_.addAll(other.email_);
-              }
-              onChanged();
-            }
-          } else {
-            if (!other.email_.isEmpty()) {
-              if (emailBuilder_.isEmpty()) {
-                emailBuilder_.dispose();
-                emailBuilder_ = null;
-                email_ = other.email_;
-                bitField0_ = (bitField0_ & ~0x00000004);
-                emailBuilder_ = 
-                  com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
-                     getEmailFieldBuilder() : null;
-              } else {
-                emailBuilder_.addAllMessages(other.email_);
-              }
-            }
-          }
-          if (addressBuilder_ == null) {
-            if (!other.address_.isEmpty()) {
-              if (address_.isEmpty()) {
-                address_ = other.address_;
-                bitField0_ = (bitField0_ & ~0x00000008);
-              } else {
-                ensureAddressIsMutable();
-                address_.addAll(other.address_);
-              }
-              onChanged();
-            }
-          } else {
-            if (!other.address_.isEmpty()) {
-              if (addressBuilder_.isEmpty()) {
-                addressBuilder_.dispose();
-                addressBuilder_ = null;
-                address_ = other.address_;
-                bitField0_ = (bitField0_ & ~0x00000008);
-                addressBuilder_ = 
-                  com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ?
-                     getAddressFieldBuilder() : null;
-              } else {
-                addressBuilder_.addAllMessages(other.address_);
-              }
-            }
-          }
-          if (other.hasAvatar()) {
-            mergeAvatar(other.getAvatar());
-          }
-          if (other.hasOrganization()) {
-            bitField0_ |= 0x00000020;
-            organization_ = other.organization_;
-            onChanged();
-          }
-          this.mergeUnknownFields(other.getUnknownFields());
-          return this;
-        }
-
-        public final boolean isInitialized() {
-          return true;
-        }
-
-        public Builder mergeFrom(
-            com.google.protobuf.CodedInputStream input,
-            com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-            throws java.io.IOException {
-          org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact parsedMessage = null;
-          try {
-            parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-          } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-            parsedMessage = (org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact) e.getUnfinishedMessage();
-            throw e;
-          } finally {
-            if (parsedMessage != null) {
-              mergeFrom(parsedMessage);
-            }
-          }
-          return this;
-        }
-        private int bitField0_;
-
-        // optional .signalservice.DataMessage.Contact.Name name = 1;
-        private org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name name_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name.getDefaultInstance();
-        private com.google.protobuf.SingleFieldBuilder<
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.NameOrBuilder> nameBuilder_;
-        /**
-         * optional .signalservice.DataMessage.Contact.Name name = 1;
-         */
-        public boolean hasName() {
-          return ((bitField0_ & 0x00000001) == 0x00000001);
-        }
-        /**
-         * optional .signalservice.DataMessage.Contact.Name name = 1;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name getName() {
-          if (nameBuilder_ == null) {
-            return name_;
-          } else {
-            return nameBuilder_.getMessage();
-          }
-        }
-        /**
-         * optional .signalservice.DataMessage.Contact.Name name = 1;
-         */
-        public Builder setName(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name value) {
-          if (nameBuilder_ == null) {
-            if (value == null) {
-              throw new NullPointerException();
-            }
-            name_ = value;
-            onChanged();
-          } else {
-            nameBuilder_.setMessage(value);
-          }
-          bitField0_ |= 0x00000001;
-          return this;
-        }
-        /**
-         * optional .signalservice.DataMessage.Contact.Name name = 1;
-         */
-        public Builder setName(
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name.Builder builderForValue) {
-          if (nameBuilder_ == null) {
-            name_ = builderForValue.build();
-            onChanged();
-          } else {
-            nameBuilder_.setMessage(builderForValue.build());
-          }
-          bitField0_ |= 0x00000001;
-          return this;
-        }
-        /**
-         * optional .signalservice.DataMessage.Contact.Name name = 1;
-         */
-        public Builder mergeName(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name value) {
-          if (nameBuilder_ == null) {
-            if (((bitField0_ & 0x00000001) == 0x00000001) &&
-                name_ != org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name.getDefaultInstance()) {
-              name_ =
-                org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name.newBuilder(name_).mergeFrom(value).buildPartial();
-            } else {
-              name_ = value;
-            }
-            onChanged();
-          } else {
-            nameBuilder_.mergeFrom(value);
-          }
-          bitField0_ |= 0x00000001;
-          return this;
-        }
-        /**
-         * optional .signalservice.DataMessage.Contact.Name name = 1;
-         */
-        public Builder clearName() {
-          if (nameBuilder_ == null) {
-            name_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name.getDefaultInstance();
-            onChanged();
-          } else {
-            nameBuilder_.clear();
-          }
-          bitField0_ = (bitField0_ & ~0x00000001);
-          return this;
-        }
-        /**
-         * optional .signalservice.DataMessage.Contact.Name name = 1;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name.Builder getNameBuilder() {
-          bitField0_ |= 0x00000001;
-          onChanged();
-          return getNameFieldBuilder().getBuilder();
-        }
-        /**
-         * optional .signalservice.DataMessage.Contact.Name name = 1;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.NameOrBuilder getNameOrBuilder() {
-          if (nameBuilder_ != null) {
-            return nameBuilder_.getMessageOrBuilder();
-          } else {
-            return name_;
-          }
-        }
-        /**
-         * optional .signalservice.DataMessage.Contact.Name name = 1;
-         */
-        private com.google.protobuf.SingleFieldBuilder<
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.NameOrBuilder> 
-            getNameFieldBuilder() {
-          if (nameBuilder_ == null) {
-            nameBuilder_ = new com.google.protobuf.SingleFieldBuilder<
-                org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Name.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.NameOrBuilder>(
-                    name_,
-                    getParentForChildren(),
-                    isClean());
-            name_ = null;
-          }
-          return nameBuilder_;
-        }
-
-        // repeated .signalservice.DataMessage.Contact.Phone number = 3;
-        private java.util.List number_ =
-          java.util.Collections.emptyList();
-        private void ensureNumberIsMutable() {
-          if (!((bitField0_ & 0x00000002) == 0x00000002)) {
-            number_ = new java.util.ArrayList(number_);
-            bitField0_ |= 0x00000002;
-           }
-        }
-
-        private com.google.protobuf.RepeatedFieldBuilder<
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PhoneOrBuilder> numberBuilder_;
-
-        /**
-         * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-         */
-        public java.util.List getNumberList() {
-          if (numberBuilder_ == null) {
-            return java.util.Collections.unmodifiableList(number_);
-          } else {
-            return numberBuilder_.getMessageList();
-          }
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-         */
-        public int getNumberCount() {
-          if (numberBuilder_ == null) {
-            return number_.size();
-          } else {
-            return numberBuilder_.getCount();
-          }
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone getNumber(int index) {
-          if (numberBuilder_ == null) {
-            return number_.get(index);
-          } else {
-            return numberBuilder_.getMessage(index);
-          }
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-         */
-        public Builder setNumber(
-            int index, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone value) {
-          if (numberBuilder_ == null) {
-            if (value == null) {
-              throw new NullPointerException();
-            }
-            ensureNumberIsMutable();
-            number_.set(index, value);
-            onChanged();
-          } else {
-            numberBuilder_.setMessage(index, value);
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-         */
-        public Builder setNumber(
-            int index, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Builder builderForValue) {
-          if (numberBuilder_ == null) {
-            ensureNumberIsMutable();
-            number_.set(index, builderForValue.build());
-            onChanged();
-          } else {
-            numberBuilder_.setMessage(index, builderForValue.build());
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-         */
-        public Builder addNumber(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone value) {
-          if (numberBuilder_ == null) {
-            if (value == null) {
-              throw new NullPointerException();
-            }
-            ensureNumberIsMutable();
-            number_.add(value);
-            onChanged();
-          } else {
-            numberBuilder_.addMessage(value);
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-         */
-        public Builder addNumber(
-            int index, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone value) {
-          if (numberBuilder_ == null) {
-            if (value == null) {
-              throw new NullPointerException();
-            }
-            ensureNumberIsMutable();
-            number_.add(index, value);
-            onChanged();
-          } else {
-            numberBuilder_.addMessage(index, value);
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-         */
-        public Builder addNumber(
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Builder builderForValue) {
-          if (numberBuilder_ == null) {
-            ensureNumberIsMutable();
-            number_.add(builderForValue.build());
-            onChanged();
-          } else {
-            numberBuilder_.addMessage(builderForValue.build());
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-         */
-        public Builder addNumber(
-            int index, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Builder builderForValue) {
-          if (numberBuilder_ == null) {
-            ensureNumberIsMutable();
-            number_.add(index, builderForValue.build());
-            onChanged();
-          } else {
-            numberBuilder_.addMessage(index, builderForValue.build());
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-         */
-        public Builder addAllNumber(
-            java.lang.Iterable values) {
-          if (numberBuilder_ == null) {
-            ensureNumberIsMutable();
-            super.addAll(values, number_);
-            onChanged();
-          } else {
-            numberBuilder_.addAllMessages(values);
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-         */
-        public Builder clearNumber() {
-          if (numberBuilder_ == null) {
-            number_ = java.util.Collections.emptyList();
-            bitField0_ = (bitField0_ & ~0x00000002);
-            onChanged();
-          } else {
-            numberBuilder_.clear();
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-         */
-        public Builder removeNumber(int index) {
-          if (numberBuilder_ == null) {
-            ensureNumberIsMutable();
-            number_.remove(index);
-            onChanged();
-          } else {
-            numberBuilder_.remove(index);
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Builder getNumberBuilder(
-            int index) {
-          return getNumberFieldBuilder().getBuilder(index);
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PhoneOrBuilder getNumberOrBuilder(
-            int index) {
-          if (numberBuilder_ == null) {
-            return number_.get(index);  } else {
-            return numberBuilder_.getMessageOrBuilder(index);
-          }
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-         */
-        public java.util.List 
-             getNumberOrBuilderList() {
-          if (numberBuilder_ != null) {
-            return numberBuilder_.getMessageOrBuilderList();
-          } else {
-            return java.util.Collections.unmodifiableList(number_);
-          }
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Builder addNumberBuilder() {
-          return getNumberFieldBuilder().addBuilder(
-              org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.getDefaultInstance());
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Builder addNumberBuilder(
-            int index) {
-          return getNumberFieldBuilder().addBuilder(
-              index, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.getDefaultInstance());
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Phone number = 3;
-         */
-        public java.util.List 
-             getNumberBuilderList() {
-          return getNumberFieldBuilder().getBuilderList();
-        }
-        private com.google.protobuf.RepeatedFieldBuilder<
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PhoneOrBuilder> 
-            getNumberFieldBuilder() {
-          if (numberBuilder_ == null) {
-            numberBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
-                org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Phone.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PhoneOrBuilder>(
-                    number_,
-                    ((bitField0_ & 0x00000002) == 0x00000002),
-                    getParentForChildren(),
-                    isClean());
-            number_ = null;
-          }
-          return numberBuilder_;
-        }
-
-        // repeated .signalservice.DataMessage.Contact.Email email = 4;
-        private java.util.List email_ =
-          java.util.Collections.emptyList();
-        private void ensureEmailIsMutable() {
-          if (!((bitField0_ & 0x00000004) == 0x00000004)) {
-            email_ = new java.util.ArrayList(email_);
-            bitField0_ |= 0x00000004;
-           }
-        }
-
-        private com.google.protobuf.RepeatedFieldBuilder<
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.EmailOrBuilder> emailBuilder_;
-
-        /**
-         * repeated .signalservice.DataMessage.Contact.Email email = 4;
-         */
-        public java.util.List getEmailList() {
-          if (emailBuilder_ == null) {
-            return java.util.Collections.unmodifiableList(email_);
-          } else {
-            return emailBuilder_.getMessageList();
-          }
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Email email = 4;
-         */
-        public int getEmailCount() {
-          if (emailBuilder_ == null) {
-            return email_.size();
-          } else {
-            return emailBuilder_.getCount();
-          }
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Email email = 4;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email getEmail(int index) {
-          if (emailBuilder_ == null) {
-            return email_.get(index);
-          } else {
-            return emailBuilder_.getMessage(index);
-          }
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Email email = 4;
-         */
-        public Builder setEmail(
-            int index, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email value) {
-          if (emailBuilder_ == null) {
-            if (value == null) {
-              throw new NullPointerException();
-            }
-            ensureEmailIsMutable();
-            email_.set(index, value);
-            onChanged();
-          } else {
-            emailBuilder_.setMessage(index, value);
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Email email = 4;
-         */
-        public Builder setEmail(
-            int index, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Builder builderForValue) {
-          if (emailBuilder_ == null) {
-            ensureEmailIsMutable();
-            email_.set(index, builderForValue.build());
-            onChanged();
-          } else {
-            emailBuilder_.setMessage(index, builderForValue.build());
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Email email = 4;
-         */
-        public Builder addEmail(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email value) {
-          if (emailBuilder_ == null) {
-            if (value == null) {
-              throw new NullPointerException();
-            }
-            ensureEmailIsMutable();
-            email_.add(value);
-            onChanged();
-          } else {
-            emailBuilder_.addMessage(value);
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Email email = 4;
-         */
-        public Builder addEmail(
-            int index, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email value) {
-          if (emailBuilder_ == null) {
-            if (value == null) {
-              throw new NullPointerException();
-            }
-            ensureEmailIsMutable();
-            email_.add(index, value);
-            onChanged();
-          } else {
-            emailBuilder_.addMessage(index, value);
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Email email = 4;
-         */
-        public Builder addEmail(
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Builder builderForValue) {
-          if (emailBuilder_ == null) {
-            ensureEmailIsMutable();
-            email_.add(builderForValue.build());
-            onChanged();
-          } else {
-            emailBuilder_.addMessage(builderForValue.build());
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Email email = 4;
-         */
-        public Builder addEmail(
-            int index, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Builder builderForValue) {
-          if (emailBuilder_ == null) {
-            ensureEmailIsMutable();
-            email_.add(index, builderForValue.build());
-            onChanged();
-          } else {
-            emailBuilder_.addMessage(index, builderForValue.build());
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Email email = 4;
-         */
-        public Builder addAllEmail(
-            java.lang.Iterable values) {
-          if (emailBuilder_ == null) {
-            ensureEmailIsMutable();
-            super.addAll(values, email_);
-            onChanged();
-          } else {
-            emailBuilder_.addAllMessages(values);
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Email email = 4;
-         */
-        public Builder clearEmail() {
-          if (emailBuilder_ == null) {
-            email_ = java.util.Collections.emptyList();
-            bitField0_ = (bitField0_ & ~0x00000004);
-            onChanged();
-          } else {
-            emailBuilder_.clear();
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Email email = 4;
-         */
-        public Builder removeEmail(int index) {
-          if (emailBuilder_ == null) {
-            ensureEmailIsMutable();
-            email_.remove(index);
-            onChanged();
-          } else {
-            emailBuilder_.remove(index);
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Email email = 4;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Builder getEmailBuilder(
-            int index) {
-          return getEmailFieldBuilder().getBuilder(index);
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Email email = 4;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.EmailOrBuilder getEmailOrBuilder(
-            int index) {
-          if (emailBuilder_ == null) {
-            return email_.get(index);  } else {
-            return emailBuilder_.getMessageOrBuilder(index);
-          }
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Email email = 4;
-         */
-        public java.util.List 
-             getEmailOrBuilderList() {
-          if (emailBuilder_ != null) {
-            return emailBuilder_.getMessageOrBuilderList();
-          } else {
-            return java.util.Collections.unmodifiableList(email_);
-          }
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Email email = 4;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Builder addEmailBuilder() {
-          return getEmailFieldBuilder().addBuilder(
-              org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.getDefaultInstance());
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Email email = 4;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Builder addEmailBuilder(
-            int index) {
-          return getEmailFieldBuilder().addBuilder(
-              index, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.getDefaultInstance());
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.Email email = 4;
-         */
-        public java.util.List 
-             getEmailBuilderList() {
-          return getEmailFieldBuilder().getBuilderList();
-        }
-        private com.google.protobuf.RepeatedFieldBuilder<
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.EmailOrBuilder> 
-            getEmailFieldBuilder() {
-          if (emailBuilder_ == null) {
-            emailBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
-                org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Email.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.EmailOrBuilder>(
-                    email_,
-                    ((bitField0_ & 0x00000004) == 0x00000004),
-                    getParentForChildren(),
-                    isClean());
-            email_ = null;
-          }
-          return emailBuilder_;
-        }
-
-        // repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-        private java.util.List address_ =
-          java.util.Collections.emptyList();
-        private void ensureAddressIsMutable() {
-          if (!((bitField0_ & 0x00000008) == 0x00000008)) {
-            address_ = new java.util.ArrayList(address_);
-            bitField0_ |= 0x00000008;
-           }
-        }
-
-        private com.google.protobuf.RepeatedFieldBuilder<
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddressOrBuilder> addressBuilder_;
-
-        /**
-         * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-         */
-        public java.util.List getAddressList() {
-          if (addressBuilder_ == null) {
-            return java.util.Collections.unmodifiableList(address_);
-          } else {
-            return addressBuilder_.getMessageList();
-          }
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-         */
-        public int getAddressCount() {
-          if (addressBuilder_ == null) {
-            return address_.size();
-          } else {
-            return addressBuilder_.getCount();
-          }
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress getAddress(int index) {
-          if (addressBuilder_ == null) {
-            return address_.get(index);
-          } else {
-            return addressBuilder_.getMessage(index);
-          }
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-         */
-        public Builder setAddress(
-            int index, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress value) {
-          if (addressBuilder_ == null) {
-            if (value == null) {
-              throw new NullPointerException();
-            }
-            ensureAddressIsMutable();
-            address_.set(index, value);
-            onChanged();
-          } else {
-            addressBuilder_.setMessage(index, value);
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-         */
-        public Builder setAddress(
-            int index, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Builder builderForValue) {
-          if (addressBuilder_ == null) {
-            ensureAddressIsMutable();
-            address_.set(index, builderForValue.build());
-            onChanged();
-          } else {
-            addressBuilder_.setMessage(index, builderForValue.build());
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-         */
-        public Builder addAddress(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress value) {
-          if (addressBuilder_ == null) {
-            if (value == null) {
-              throw new NullPointerException();
-            }
-            ensureAddressIsMutable();
-            address_.add(value);
-            onChanged();
-          } else {
-            addressBuilder_.addMessage(value);
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-         */
-        public Builder addAddress(
-            int index, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress value) {
-          if (addressBuilder_ == null) {
-            if (value == null) {
-              throw new NullPointerException();
-            }
-            ensureAddressIsMutable();
-            address_.add(index, value);
-            onChanged();
-          } else {
-            addressBuilder_.addMessage(index, value);
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-         */
-        public Builder addAddress(
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Builder builderForValue) {
-          if (addressBuilder_ == null) {
-            ensureAddressIsMutable();
-            address_.add(builderForValue.build());
-            onChanged();
-          } else {
-            addressBuilder_.addMessage(builderForValue.build());
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-         */
-        public Builder addAddress(
-            int index, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Builder builderForValue) {
-          if (addressBuilder_ == null) {
-            ensureAddressIsMutable();
-            address_.add(index, builderForValue.build());
-            onChanged();
-          } else {
-            addressBuilder_.addMessage(index, builderForValue.build());
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-         */
-        public Builder addAllAddress(
-            java.lang.Iterable values) {
-          if (addressBuilder_ == null) {
-            ensureAddressIsMutable();
-            super.addAll(values, address_);
-            onChanged();
-          } else {
-            addressBuilder_.addAllMessages(values);
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-         */
-        public Builder clearAddress() {
-          if (addressBuilder_ == null) {
-            address_ = java.util.Collections.emptyList();
-            bitField0_ = (bitField0_ & ~0x00000008);
-            onChanged();
-          } else {
-            addressBuilder_.clear();
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-         */
-        public Builder removeAddress(int index) {
-          if (addressBuilder_ == null) {
-            ensureAddressIsMutable();
-            address_.remove(index);
-            onChanged();
-          } else {
-            addressBuilder_.remove(index);
-          }
-          return this;
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Builder getAddressBuilder(
-            int index) {
-          return getAddressFieldBuilder().getBuilder(index);
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddressOrBuilder getAddressOrBuilder(
-            int index) {
-          if (addressBuilder_ == null) {
-            return address_.get(index);  } else {
-            return addressBuilder_.getMessageOrBuilder(index);
-          }
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-         */
-        public java.util.List 
-             getAddressOrBuilderList() {
-          if (addressBuilder_ != null) {
-            return addressBuilder_.getMessageOrBuilderList();
-          } else {
-            return java.util.Collections.unmodifiableList(address_);
-          }
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Builder addAddressBuilder() {
-          return getAddressFieldBuilder().addBuilder(
-              org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.getDefaultInstance());
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Builder addAddressBuilder(
-            int index) {
-          return getAddressFieldBuilder().addBuilder(
-              index, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.getDefaultInstance());
-        }
-        /**
-         * repeated .signalservice.DataMessage.Contact.PostalAddress address = 5;
-         */
-        public java.util.List 
-             getAddressBuilderList() {
-          return getAddressFieldBuilder().getBuilderList();
-        }
-        private com.google.protobuf.RepeatedFieldBuilder<
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddressOrBuilder> 
-            getAddressFieldBuilder() {
-          if (addressBuilder_ == null) {
-            addressBuilder_ = new com.google.protobuf.RepeatedFieldBuilder<
-                org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddress.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.PostalAddressOrBuilder>(
-                    address_,
-                    ((bitField0_ & 0x00000008) == 0x00000008),
-                    getParentForChildren(),
-                    isClean());
-            address_ = null;
-          }
-          return addressBuilder_;
-        }
-
-        // optional .signalservice.DataMessage.Contact.Avatar avatar = 6;
-        private org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar avatar_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar.getDefaultInstance();
-        private com.google.protobuf.SingleFieldBuilder<
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.AvatarOrBuilder> avatarBuilder_;
-        /**
-         * optional .signalservice.DataMessage.Contact.Avatar avatar = 6;
-         */
-        public boolean hasAvatar() {
-          return ((bitField0_ & 0x00000010) == 0x00000010);
-        }
-        /**
-         * optional .signalservice.DataMessage.Contact.Avatar avatar = 6;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar getAvatar() {
-          if (avatarBuilder_ == null) {
-            return avatar_;
-          } else {
-            return avatarBuilder_.getMessage();
-          }
-        }
-        /**
-         * optional .signalservice.DataMessage.Contact.Avatar avatar = 6;
-         */
-        public Builder setAvatar(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar value) {
-          if (avatarBuilder_ == null) {
-            if (value == null) {
-              throw new NullPointerException();
-            }
-            avatar_ = value;
-            onChanged();
-          } else {
-            avatarBuilder_.setMessage(value);
-          }
-          bitField0_ |= 0x00000010;
-          return this;
-        }
-        /**
-         * optional .signalservice.DataMessage.Contact.Avatar avatar = 6;
-         */
-        public Builder setAvatar(
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar.Builder builderForValue) {
-          if (avatarBuilder_ == null) {
-            avatar_ = builderForValue.build();
-            onChanged();
-          } else {
-            avatarBuilder_.setMessage(builderForValue.build());
-          }
-          bitField0_ |= 0x00000010;
-          return this;
-        }
-        /**
-         * optional .signalservice.DataMessage.Contact.Avatar avatar = 6;
-         */
-        public Builder mergeAvatar(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar value) {
-          if (avatarBuilder_ == null) {
-            if (((bitField0_ & 0x00000010) == 0x00000010) &&
-                avatar_ != org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar.getDefaultInstance()) {
-              avatar_ =
-                org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar.newBuilder(avatar_).mergeFrom(value).buildPartial();
-            } else {
-              avatar_ = value;
-            }
-            onChanged();
-          } else {
-            avatarBuilder_.mergeFrom(value);
-          }
-          bitField0_ |= 0x00000010;
-          return this;
-        }
-        /**
-         * optional .signalservice.DataMessage.Contact.Avatar avatar = 6;
-         */
-        public Builder clearAvatar() {
-          if (avatarBuilder_ == null) {
-            avatar_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar.getDefaultInstance();
-            onChanged();
-          } else {
-            avatarBuilder_.clear();
-          }
-          bitField0_ = (bitField0_ & ~0x00000010);
-          return this;
-        }
-        /**
-         * optional .signalservice.DataMessage.Contact.Avatar avatar = 6;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar.Builder getAvatarBuilder() {
-          bitField0_ |= 0x00000010;
-          onChanged();
-          return getAvatarFieldBuilder().getBuilder();
-        }
-        /**
-         * optional .signalservice.DataMessage.Contact.Avatar avatar = 6;
-         */
-        public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.AvatarOrBuilder getAvatarOrBuilder() {
-          if (avatarBuilder_ != null) {
-            return avatarBuilder_.getMessageOrBuilder();
-          } else {
-            return avatar_;
-          }
-        }
-        /**
-         * optional .signalservice.DataMessage.Contact.Avatar avatar = 6;
-         */
-        private com.google.protobuf.SingleFieldBuilder<
-            org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.AvatarOrBuilder> 
-            getAvatarFieldBuilder() {
-          if (avatarBuilder_ == null) {
-            avatarBuilder_ = new com.google.protobuf.SingleFieldBuilder<
-                org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Avatar.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.AvatarOrBuilder>(
-                    avatar_,
-                    getParentForChildren(),
-                    isClean());
-            avatar_ = null;
-          }
-          return avatarBuilder_;
-        }
-
-        // optional string organization = 7;
-        private java.lang.Object organization_ = "";
-        /**
-         * optional string organization = 7;
-         */
-        public boolean hasOrganization() {
-          return ((bitField0_ & 0x00000020) == 0x00000020);
-        }
-        /**
-         * optional string organization = 7;
-         */
-        public java.lang.String getOrganization() {
-          java.lang.Object ref = organization_;
-          if (!(ref instanceof java.lang.String)) {
-            java.lang.String s = ((com.google.protobuf.ByteString) ref)
-                .toStringUtf8();
-            organization_ = s;
-            return s;
-          } else {
-            return (java.lang.String) ref;
-          }
-        }
-        /**
-         * optional string organization = 7;
-         */
-        public com.google.protobuf.ByteString
-            getOrganizationBytes() {
-          java.lang.Object ref = organization_;
-          if (ref instanceof String) {
-            com.google.protobuf.ByteString b = 
-                com.google.protobuf.ByteString.copyFromUtf8(
-                    (java.lang.String) ref);
-            organization_ = b;
-            return b;
-          } else {
-            return (com.google.protobuf.ByteString) ref;
-          }
-        }
-        /**
-         * optional string organization = 7;
-         */
-        public Builder setOrganization(
-            java.lang.String value) {
-          if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000020;
-          organization_ = value;
-          onChanged();
-          return this;
-        }
-        /**
-         * optional string organization = 7;
-         */
-        public Builder clearOrganization() {
-          bitField0_ = (bitField0_ & ~0x00000020);
-          organization_ = getDefaultInstance().getOrganization();
-          onChanged();
-          return this;
-        }
-        /**
-         * optional string organization = 7;
-         */
-        public Builder setOrganizationBytes(
-            com.google.protobuf.ByteString value) {
-          if (value == null) {
-    throw new NullPointerException();
-  }
-  bitField0_ |= 0x00000020;
-          organization_ = value;
-          onChanged();
-          return this;
-        }
-
-        // @@protoc_insertion_point(builder_scope:signalservice.DataMessage.Contact)
-      }
-
-      static {
-        defaultInstance = new Contact(true);
-        defaultInstance.initFields();
-      }
-
-      // @@protoc_insertion_point(class_scope:signalservice.DataMessage.Contact)
-    }
-
     public interface PreviewOrBuilder
         extends com.google.protobuf.MessageOrBuilder {
 
-      // optional string url = 1;
+      // required string url = 1;
       /**
-       * optional string url = 1;
+       * required string url = 1;
        *
        * 
        * @required
@@ -14522,7 +6842,7 @@ public final class SignalServiceProtos {
        */
       boolean hasUrl();
       /**
-       * optional string url = 1;
+       * required string url = 1;
        *
        * 
        * @required
@@ -14530,7 +6850,7 @@ public final class SignalServiceProtos {
        */
       java.lang.String getUrl();
       /**
-       * optional string url = 1;
+       * required string url = 1;
        *
        * 
        * @required
@@ -14682,11 +7002,11 @@ public final class SignalServiceProtos {
       }
 
       private int bitField0_;
-      // optional string url = 1;
+      // required string url = 1;
       public static final int URL_FIELD_NUMBER = 1;
       private java.lang.Object url_;
       /**
-       * optional string url = 1;
+       * required string url = 1;
        *
        * 
        * @required
@@ -14696,7 +7016,7 @@ public final class SignalServiceProtos {
         return ((bitField0_ & 0x00000001) == 0x00000001);
       }
       /**
-       * optional string url = 1;
+       * required string url = 1;
        *
        * 
        * @required
@@ -14717,7 +7037,7 @@ public final class SignalServiceProtos {
         }
       }
       /**
-       * optional string url = 1;
+       * required string url = 1;
        *
        * 
        * @required
@@ -14812,6 +7132,16 @@ public final class SignalServiceProtos {
         byte isInitialized = memoizedIsInitialized;
         if (isInitialized != -1) return isInitialized == 1;
 
+        if (!hasUrl()) {
+          memoizedIsInitialized = 0;
+          return false;
+        }
+        if (hasImage()) {
+          if (!getImage().isInitialized()) {
+            memoizedIsInitialized = 0;
+            return false;
+          }
+        }
         memoizedIsInitialized = 1;
         return true;
       }
@@ -15054,6 +7384,16 @@ public final class SignalServiceProtos {
         }
 
         public final boolean isInitialized() {
+          if (!hasUrl()) {
+            
+            return false;
+          }
+          if (hasImage()) {
+            if (!getImage().isInitialized()) {
+              
+              return false;
+            }
+          }
           return true;
         }
 
@@ -15076,10 +7416,10 @@ public final class SignalServiceProtos {
         }
         private int bitField0_;
 
-        // optional string url = 1;
+        // required string url = 1;
         private java.lang.Object url_ = "";
         /**
-         * optional string url = 1;
+         * required string url = 1;
          *
          * 
          * @required
@@ -15089,7 +7429,7 @@ public final class SignalServiceProtos {
           return ((bitField0_ & 0x00000001) == 0x00000001);
         }
         /**
-         * optional string url = 1;
+         * required string url = 1;
          *
          * 
          * @required
@@ -15107,7 +7447,7 @@ public final class SignalServiceProtos {
           }
         }
         /**
-         * optional string url = 1;
+         * required string url = 1;
          *
          * 
          * @required
@@ -15127,7 +7467,7 @@ public final class SignalServiceProtos {
           }
         }
         /**
-         * optional string url = 1;
+         * required string url = 1;
          *
          * 
          * @required
@@ -15144,7 +7484,7 @@ public final class SignalServiceProtos {
           return this;
         }
         /**
-         * optional string url = 1;
+         * required string url = 1;
          *
          * 
          * @required
@@ -15157,7 +7497,7 @@ public final class SignalServiceProtos {
           return this;
         }
         /**
-         * optional string url = 1;
+         * required string url = 1;
          *
          * 
          * @required
@@ -16286,14 +8626,6 @@ public final class SignalServiceProtos {
          * 
*/ NEW(0, 1), - /** - * UPDATE = 2; - * - *
-         * name, members
-         * 
- */ - UPDATE(1, 2), /** * ENCRYPTION_KEY_PAIR = 3; * @@ -16301,7 +8633,7 @@ public final class SignalServiceProtos { * publicKey, wrappers *
*/ - ENCRYPTION_KEY_PAIR(2, 3), + ENCRYPTION_KEY_PAIR(1, 3), /** * NAME_CHANGE = 4; * @@ -16309,7 +8641,7 @@ public final class SignalServiceProtos { * name *
*/ - NAME_CHANGE(3, 4), + NAME_CHANGE(2, 4), /** * MEMBERS_ADDED = 5; * @@ -16317,7 +8649,7 @@ public final class SignalServiceProtos { * members *
*/ - MEMBERS_ADDED(4, 5), + MEMBERS_ADDED(3, 5), /** * MEMBERS_REMOVED = 6; * @@ -16325,15 +8657,11 @@ public final class SignalServiceProtos { * members *
*/ - MEMBERS_REMOVED(5, 6), + MEMBERS_REMOVED(4, 6), /** * MEMBER_LEFT = 7; */ - MEMBER_LEFT(6, 7), - /** - * ENCRYPTION_KEY_PAIR_REQUEST = 8; - */ - ENCRYPTION_KEY_PAIR_REQUEST(7, 8), + MEMBER_LEFT(5, 7), ; /** @@ -16344,14 +8672,6 @@ public final class SignalServiceProtos { *
*/ public static final int NEW_VALUE = 1; - /** - * UPDATE = 2; - * - *
-         * name, members
-         * 
- */ - public static final int UPDATE_VALUE = 2; /** * ENCRYPTION_KEY_PAIR = 3; * @@ -16388,10 +8708,6 @@ public final class SignalServiceProtos { * MEMBER_LEFT = 7; */ public static final int MEMBER_LEFT_VALUE = 7; - /** - * ENCRYPTION_KEY_PAIR_REQUEST = 8; - */ - public static final int ENCRYPTION_KEY_PAIR_REQUEST_VALUE = 8; public final int getNumber() { return value; } @@ -16399,13 +8715,11 @@ public final class SignalServiceProtos { public static Type valueOf(int value) { switch (value) { case 1: return NEW; - case 2: return UPDATE; case 3: return ENCRYPTION_KEY_PAIR; case 4: return NAME_CHANGE; case 5: return MEMBERS_ADDED; case 6: return MEMBERS_REMOVED; case 7: return MEMBER_LEFT; - case 8: return ENCRYPTION_KEY_PAIR_REQUEST; default: return null; } } @@ -18501,42 +10815,6 @@ public final class SignalServiceProtos { return quote_; } - // repeated .signalservice.DataMessage.Contact contact = 9; - public static final int CONTACT_FIELD_NUMBER = 9; - private java.util.List contact_; - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public java.util.List getContactList() { - return contact_; - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public java.util.List - getContactOrBuilderList() { - return contact_; - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public int getContactCount() { - return contact_.size(); - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact getContact(int index) { - return contact_.get(index); - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.ContactOrBuilder getContactOrBuilder( - int index) { - return contact_.get(index); - } - // repeated .signalservice.DataMessage.Preview preview = 10; public static final int PREVIEW_FIELD_NUMBER = 10; private java.util.List preview_; @@ -18660,28 +10938,6 @@ public final class SignalServiceProtos { } } - // optional .signalservice.PublicChatInfo publicChatInfo = 999; - public static final int PUBLICCHATINFO_FIELD_NUMBER = 999; - private org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo publicChatInfo_; - /** - * optional .signalservice.PublicChatInfo publicChatInfo = 999; - */ - public boolean hasPublicChatInfo() { - return ((bitField0_ & 0x00000400) == 0x00000400); - } - /** - * optional .signalservice.PublicChatInfo publicChatInfo = 999; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo getPublicChatInfo() { - return publicChatInfo_; - } - /** - * optional .signalservice.PublicChatInfo publicChatInfo = 999; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfoOrBuilder getPublicChatInfoOrBuilder() { - return publicChatInfo_; - } - private void initFields() { body_ = ""; attachments_ = java.util.Collections.emptyList(); @@ -18691,18 +10947,40 @@ public final class SignalServiceProtos { profileKey_ = com.google.protobuf.ByteString.EMPTY; timestamp_ = 0L; quote_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Quote.getDefaultInstance(); - contact_ = java.util.Collections.emptyList(); preview_ = java.util.Collections.emptyList(); profile_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.LokiProfile.getDefaultInstance(); closedGroupControlMessage_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.ClosedGroupControlMessage.getDefaultInstance(); syncTarget_ = ""; - publicChatInfo_ = org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo.getDefaultInstance(); } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized != -1) return isInitialized == 1; + for (int i = 0; i < getAttachmentsCount(); i++) { + if (!getAttachments(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + if (hasGroup()) { + if (!getGroup().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + if (hasQuote()) { + if (!getQuote().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } + for (int i = 0; i < getPreviewCount(); i++) { + if (!getPreview(i).isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } if (hasClosedGroupControlMessage()) { if (!getClosedGroupControlMessage().isInitialized()) { memoizedIsInitialized = 0; @@ -18740,9 +11018,6 @@ public final class SignalServiceProtos { if (((bitField0_ & 0x00000040) == 0x00000040)) { output.writeMessage(8, quote_); } - for (int i = 0; i < contact_.size(); i++) { - output.writeMessage(9, contact_.get(i)); - } for (int i = 0; i < preview_.size(); i++) { output.writeMessage(10, preview_.get(i)); } @@ -18755,9 +11030,6 @@ public final class SignalServiceProtos { if (((bitField0_ & 0x00000200) == 0x00000200)) { output.writeBytes(105, getSyncTargetBytes()); } - if (((bitField0_ & 0x00000400) == 0x00000400)) { - output.writeMessage(999, publicChatInfo_); - } getUnknownFields().writeTo(output); } @@ -18799,10 +11071,6 @@ public final class SignalServiceProtos { size += com.google.protobuf.CodedOutputStream .computeMessageSize(8, quote_); } - for (int i = 0; i < contact_.size(); i++) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(9, contact_.get(i)); - } for (int i = 0; i < preview_.size(); i++) { size += com.google.protobuf.CodedOutputStream .computeMessageSize(10, preview_.get(i)); @@ -18819,10 +11087,6 @@ public final class SignalServiceProtos { size += com.google.protobuf.CodedOutputStream .computeBytesSize(105, getSyncTargetBytes()); } - if (((bitField0_ & 0x00000400) == 0x00000400)) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(999, publicChatInfo_); - } size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; return size; @@ -18934,11 +11198,9 @@ public final class SignalServiceProtos { getAttachmentsFieldBuilder(); getGroupFieldBuilder(); getQuoteFieldBuilder(); - getContactFieldBuilder(); getPreviewFieldBuilder(); getProfileFieldBuilder(); getClosedGroupControlMessageFieldBuilder(); - getPublicChatInfoFieldBuilder(); } } private static Builder create() { @@ -18975,15 +11237,9 @@ public final class SignalServiceProtos { quoteBuilder_.clear(); } bitField0_ = (bitField0_ & ~0x00000080); - if (contactBuilder_ == null) { - contact_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000100); - } else { - contactBuilder_.clear(); - } if (previewBuilder_ == null) { preview_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000200); + bitField0_ = (bitField0_ & ~0x00000100); } else { previewBuilder_.clear(); } @@ -18992,21 +11248,15 @@ public final class SignalServiceProtos { } else { profileBuilder_.clear(); } - bitField0_ = (bitField0_ & ~0x00000400); + bitField0_ = (bitField0_ & ~0x00000200); if (closedGroupControlMessageBuilder_ == null) { closedGroupControlMessage_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.ClosedGroupControlMessage.getDefaultInstance(); } else { closedGroupControlMessageBuilder_.clear(); } - bitField0_ = (bitField0_ & ~0x00000800); + bitField0_ = (bitField0_ & ~0x00000400); syncTarget_ = ""; - bitField0_ = (bitField0_ & ~0x00001000); - if (publicChatInfoBuilder_ == null) { - publicChatInfo_ = org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo.getDefaultInstance(); - } else { - publicChatInfoBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00002000); + bitField0_ = (bitField0_ & ~0x00000800); return this; } @@ -19080,25 +11330,16 @@ public final class SignalServiceProtos { } else { result.quote_ = quoteBuilder_.build(); } - if (contactBuilder_ == null) { - if (((bitField0_ & 0x00000100) == 0x00000100)) { - contact_ = java.util.Collections.unmodifiableList(contact_); - bitField0_ = (bitField0_ & ~0x00000100); - } - result.contact_ = contact_; - } else { - result.contact_ = contactBuilder_.build(); - } if (previewBuilder_ == null) { - if (((bitField0_ & 0x00000200) == 0x00000200)) { + if (((bitField0_ & 0x00000100) == 0x00000100)) { preview_ = java.util.Collections.unmodifiableList(preview_); - bitField0_ = (bitField0_ & ~0x00000200); + bitField0_ = (bitField0_ & ~0x00000100); } result.preview_ = preview_; } else { result.preview_ = previewBuilder_.build(); } - if (((from_bitField0_ & 0x00000400) == 0x00000400)) { + if (((from_bitField0_ & 0x00000200) == 0x00000200)) { to_bitField0_ |= 0x00000080; } if (profileBuilder_ == null) { @@ -19106,7 +11347,7 @@ public final class SignalServiceProtos { } else { result.profile_ = profileBuilder_.build(); } - if (((from_bitField0_ & 0x00000800) == 0x00000800)) { + if (((from_bitField0_ & 0x00000400) == 0x00000400)) { to_bitField0_ |= 0x00000100; } if (closedGroupControlMessageBuilder_ == null) { @@ -19114,18 +11355,10 @@ public final class SignalServiceProtos { } else { result.closedGroupControlMessage_ = closedGroupControlMessageBuilder_.build(); } - if (((from_bitField0_ & 0x00001000) == 0x00001000)) { + if (((from_bitField0_ & 0x00000800) == 0x00000800)) { to_bitField0_ |= 0x00000200; } result.syncTarget_ = syncTarget_; - if (((from_bitField0_ & 0x00002000) == 0x00002000)) { - to_bitField0_ |= 0x00000400; - } - if (publicChatInfoBuilder_ == null) { - result.publicChatInfo_ = publicChatInfo_; - } else { - result.publicChatInfo_ = publicChatInfoBuilder_.build(); - } result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -19191,37 +11424,11 @@ public final class SignalServiceProtos { if (other.hasQuote()) { mergeQuote(other.getQuote()); } - if (contactBuilder_ == null) { - if (!other.contact_.isEmpty()) { - if (contact_.isEmpty()) { - contact_ = other.contact_; - bitField0_ = (bitField0_ & ~0x00000100); - } else { - ensureContactIsMutable(); - contact_.addAll(other.contact_); - } - onChanged(); - } - } else { - if (!other.contact_.isEmpty()) { - if (contactBuilder_.isEmpty()) { - contactBuilder_.dispose(); - contactBuilder_ = null; - contact_ = other.contact_; - bitField0_ = (bitField0_ & ~0x00000100); - contactBuilder_ = - com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? - getContactFieldBuilder() : null; - } else { - contactBuilder_.addAllMessages(other.contact_); - } - } - } if (previewBuilder_ == null) { if (!other.preview_.isEmpty()) { if (preview_.isEmpty()) { preview_ = other.preview_; - bitField0_ = (bitField0_ & ~0x00000200); + bitField0_ = (bitField0_ & ~0x00000100); } else { ensurePreviewIsMutable(); preview_.addAll(other.preview_); @@ -19234,7 +11441,7 @@ public final class SignalServiceProtos { previewBuilder_.dispose(); previewBuilder_ = null; preview_ = other.preview_; - bitField0_ = (bitField0_ & ~0x00000200); + bitField0_ = (bitField0_ & ~0x00000100); previewBuilder_ = com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders ? getPreviewFieldBuilder() : null; @@ -19250,18 +11457,39 @@ public final class SignalServiceProtos { mergeClosedGroupControlMessage(other.getClosedGroupControlMessage()); } if (other.hasSyncTarget()) { - bitField0_ |= 0x00001000; + bitField0_ |= 0x00000800; syncTarget_ = other.syncTarget_; onChanged(); } - if (other.hasPublicChatInfo()) { - mergePublicChatInfo(other.getPublicChatInfo()); - } this.mergeUnknownFields(other.getUnknownFields()); return this; } public final boolean isInitialized() { + for (int i = 0; i < getAttachmentsCount(); i++) { + if (!getAttachments(i).isInitialized()) { + + return false; + } + } + if (hasGroup()) { + if (!getGroup().isInitialized()) { + + return false; + } + } + if (hasQuote()) { + if (!getQuote().isInitialized()) { + + return false; + } + } + for (int i = 0; i < getPreviewCount(); i++) { + if (!getPreview(i).isInitialized()) { + + return false; + } + } if (hasClosedGroupControlMessage()) { if (!getClosedGroupControlMessage().isInitialized()) { @@ -19973,253 +12201,13 @@ public final class SignalServiceProtos { return quoteBuilder_; } - // repeated .signalservice.DataMessage.Contact contact = 9; - private java.util.List contact_ = - java.util.Collections.emptyList(); - private void ensureContactIsMutable() { - if (!((bitField0_ & 0x00000100) == 0x00000100)) { - contact_ = new java.util.ArrayList(contact_); - bitField0_ |= 0x00000100; - } - } - - private com.google.protobuf.RepeatedFieldBuilder< - org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.ContactOrBuilder> contactBuilder_; - - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public java.util.List getContactList() { - if (contactBuilder_ == null) { - return java.util.Collections.unmodifiableList(contact_); - } else { - return contactBuilder_.getMessageList(); - } - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public int getContactCount() { - if (contactBuilder_ == null) { - return contact_.size(); - } else { - return contactBuilder_.getCount(); - } - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact getContact(int index) { - if (contactBuilder_ == null) { - return contact_.get(index); - } else { - return contactBuilder_.getMessage(index); - } - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public Builder setContact( - int index, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact value) { - if (contactBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureContactIsMutable(); - contact_.set(index, value); - onChanged(); - } else { - contactBuilder_.setMessage(index, value); - } - return this; - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public Builder setContact( - int index, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Builder builderForValue) { - if (contactBuilder_ == null) { - ensureContactIsMutable(); - contact_.set(index, builderForValue.build()); - onChanged(); - } else { - contactBuilder_.setMessage(index, builderForValue.build()); - } - return this; - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public Builder addContact(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact value) { - if (contactBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureContactIsMutable(); - contact_.add(value); - onChanged(); - } else { - contactBuilder_.addMessage(value); - } - return this; - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public Builder addContact( - int index, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact value) { - if (contactBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - ensureContactIsMutable(); - contact_.add(index, value); - onChanged(); - } else { - contactBuilder_.addMessage(index, value); - } - return this; - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public Builder addContact( - org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Builder builderForValue) { - if (contactBuilder_ == null) { - ensureContactIsMutable(); - contact_.add(builderForValue.build()); - onChanged(); - } else { - contactBuilder_.addMessage(builderForValue.build()); - } - return this; - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public Builder addContact( - int index, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Builder builderForValue) { - if (contactBuilder_ == null) { - ensureContactIsMutable(); - contact_.add(index, builderForValue.build()); - onChanged(); - } else { - contactBuilder_.addMessage(index, builderForValue.build()); - } - return this; - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public Builder addAllContact( - java.lang.Iterable values) { - if (contactBuilder_ == null) { - ensureContactIsMutable(); - super.addAll(values, contact_); - onChanged(); - } else { - contactBuilder_.addAllMessages(values); - } - return this; - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public Builder clearContact() { - if (contactBuilder_ == null) { - contact_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000100); - onChanged(); - } else { - contactBuilder_.clear(); - } - return this; - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public Builder removeContact(int index) { - if (contactBuilder_ == null) { - ensureContactIsMutable(); - contact_.remove(index); - onChanged(); - } else { - contactBuilder_.remove(index); - } - return this; - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Builder getContactBuilder( - int index) { - return getContactFieldBuilder().getBuilder(index); - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.ContactOrBuilder getContactOrBuilder( - int index) { - if (contactBuilder_ == null) { - return contact_.get(index); } else { - return contactBuilder_.getMessageOrBuilder(index); - } - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public java.util.List - getContactOrBuilderList() { - if (contactBuilder_ != null) { - return contactBuilder_.getMessageOrBuilderList(); - } else { - return java.util.Collections.unmodifiableList(contact_); - } - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Builder addContactBuilder() { - return getContactFieldBuilder().addBuilder( - org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.getDefaultInstance()); - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Builder addContactBuilder( - int index) { - return getContactFieldBuilder().addBuilder( - index, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.getDefaultInstance()); - } - /** - * repeated .signalservice.DataMessage.Contact contact = 9; - */ - public java.util.List - getContactBuilderList() { - return getContactFieldBuilder().getBuilderList(); - } - private com.google.protobuf.RepeatedFieldBuilder< - org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.ContactOrBuilder> - getContactFieldBuilder() { - if (contactBuilder_ == null) { - contactBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< - org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Contact.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.ContactOrBuilder>( - contact_, - ((bitField0_ & 0x00000100) == 0x00000100), - getParentForChildren(), - isClean()); - contact_ = null; - } - return contactBuilder_; - } - // repeated .signalservice.DataMessage.Preview preview = 10; private java.util.List preview_ = java.util.Collections.emptyList(); private void ensurePreviewIsMutable() { - if (!((bitField0_ & 0x00000200) == 0x00000200)) { + if (!((bitField0_ & 0x00000100) == 0x00000100)) { preview_ = new java.util.ArrayList(preview_); - bitField0_ |= 0x00000200; + bitField0_ |= 0x00000100; } } @@ -20368,7 +12356,7 @@ public final class SignalServiceProtos { public Builder clearPreview() { if (previewBuilder_ == null) { preview_ = java.util.Collections.emptyList(); - bitField0_ = (bitField0_ & ~0x00000200); + bitField0_ = (bitField0_ & ~0x00000100); onChanged(); } else { previewBuilder_.clear(); @@ -20445,7 +12433,7 @@ public final class SignalServiceProtos { previewBuilder_ = new com.google.protobuf.RepeatedFieldBuilder< org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Preview, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.Preview.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.PreviewOrBuilder>( preview_, - ((bitField0_ & 0x00000200) == 0x00000200), + ((bitField0_ & 0x00000100) == 0x00000100), getParentForChildren(), isClean()); preview_ = null; @@ -20461,7 +12449,7 @@ public final class SignalServiceProtos { * optional .signalservice.DataMessage.LokiProfile profile = 101; */ public boolean hasProfile() { - return ((bitField0_ & 0x00000400) == 0x00000400); + return ((bitField0_ & 0x00000200) == 0x00000200); } /** * optional .signalservice.DataMessage.LokiProfile profile = 101; @@ -20486,7 +12474,7 @@ public final class SignalServiceProtos { } else { profileBuilder_.setMessage(value); } - bitField0_ |= 0x00000400; + bitField0_ |= 0x00000200; return this; } /** @@ -20500,7 +12488,7 @@ public final class SignalServiceProtos { } else { profileBuilder_.setMessage(builderForValue.build()); } - bitField0_ |= 0x00000400; + bitField0_ |= 0x00000200; return this; } /** @@ -20508,7 +12496,7 @@ public final class SignalServiceProtos { */ public Builder mergeProfile(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.LokiProfile value) { if (profileBuilder_ == null) { - if (((bitField0_ & 0x00000400) == 0x00000400) && + if (((bitField0_ & 0x00000200) == 0x00000200) && profile_ != org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.LokiProfile.getDefaultInstance()) { profile_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.LokiProfile.newBuilder(profile_).mergeFrom(value).buildPartial(); @@ -20519,7 +12507,7 @@ public final class SignalServiceProtos { } else { profileBuilder_.mergeFrom(value); } - bitField0_ |= 0x00000400; + bitField0_ |= 0x00000200; return this; } /** @@ -20532,14 +12520,14 @@ public final class SignalServiceProtos { } else { profileBuilder_.clear(); } - bitField0_ = (bitField0_ & ~0x00000400); + bitField0_ = (bitField0_ & ~0x00000200); return this; } /** * optional .signalservice.DataMessage.LokiProfile profile = 101; */ public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.LokiProfile.Builder getProfileBuilder() { - bitField0_ |= 0x00000400; + bitField0_ |= 0x00000200; onChanged(); return getProfileFieldBuilder().getBuilder(); } @@ -20578,7 +12566,7 @@ public final class SignalServiceProtos { * optional .signalservice.DataMessage.ClosedGroupControlMessage closedGroupControlMessage = 104; */ public boolean hasClosedGroupControlMessage() { - return ((bitField0_ & 0x00000800) == 0x00000800); + return ((bitField0_ & 0x00000400) == 0x00000400); } /** * optional .signalservice.DataMessage.ClosedGroupControlMessage closedGroupControlMessage = 104; @@ -20603,7 +12591,7 @@ public final class SignalServiceProtos { } else { closedGroupControlMessageBuilder_.setMessage(value); } - bitField0_ |= 0x00000800; + bitField0_ |= 0x00000400; return this; } /** @@ -20617,7 +12605,7 @@ public final class SignalServiceProtos { } else { closedGroupControlMessageBuilder_.setMessage(builderForValue.build()); } - bitField0_ |= 0x00000800; + bitField0_ |= 0x00000400; return this; } /** @@ -20625,7 +12613,7 @@ public final class SignalServiceProtos { */ public Builder mergeClosedGroupControlMessage(org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.ClosedGroupControlMessage value) { if (closedGroupControlMessageBuilder_ == null) { - if (((bitField0_ & 0x00000800) == 0x00000800) && + if (((bitField0_ & 0x00000400) == 0x00000400) && closedGroupControlMessage_ != org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.ClosedGroupControlMessage.getDefaultInstance()) { closedGroupControlMessage_ = org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.ClosedGroupControlMessage.newBuilder(closedGroupControlMessage_).mergeFrom(value).buildPartial(); @@ -20636,7 +12624,7 @@ public final class SignalServiceProtos { } else { closedGroupControlMessageBuilder_.mergeFrom(value); } - bitField0_ |= 0x00000800; + bitField0_ |= 0x00000400; return this; } /** @@ -20649,14 +12637,14 @@ public final class SignalServiceProtos { } else { closedGroupControlMessageBuilder_.clear(); } - bitField0_ = (bitField0_ & ~0x00000800); + bitField0_ = (bitField0_ & ~0x00000400); return this; } /** * optional .signalservice.DataMessage.ClosedGroupControlMessage closedGroupControlMessage = 104; */ public org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.ClosedGroupControlMessage.Builder getClosedGroupControlMessageBuilder() { - bitField0_ |= 0x00000800; + bitField0_ |= 0x00000400; onChanged(); return getClosedGroupControlMessageFieldBuilder().getBuilder(); } @@ -20693,7 +12681,7 @@ public final class SignalServiceProtos { * optional string syncTarget = 105; */ public boolean hasSyncTarget() { - return ((bitField0_ & 0x00001000) == 0x00001000); + return ((bitField0_ & 0x00000800) == 0x00000800); } /** * optional string syncTarget = 105; @@ -20733,7 +12721,7 @@ public final class SignalServiceProtos { if (value == null) { throw new NullPointerException(); } - bitField0_ |= 0x00001000; + bitField0_ |= 0x00000800; syncTarget_ = value; onChanged(); return this; @@ -20742,7 +12730,7 @@ public final class SignalServiceProtos { * optional string syncTarget = 105; */ public Builder clearSyncTarget() { - bitField0_ = (bitField0_ & ~0x00001000); + bitField0_ = (bitField0_ & ~0x00000800); syncTarget_ = getDefaultInstance().getSyncTarget(); onChanged(); return this; @@ -20755,129 +12743,12 @@ public final class SignalServiceProtos { if (value == null) { throw new NullPointerException(); } - bitField0_ |= 0x00001000; + bitField0_ |= 0x00000800; syncTarget_ = value; onChanged(); return this; } - // optional .signalservice.PublicChatInfo publicChatInfo = 999; - private org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo publicChatInfo_ = org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo.getDefaultInstance(); - private com.google.protobuf.SingleFieldBuilder< - org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo, org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfoOrBuilder> publicChatInfoBuilder_; - /** - * optional .signalservice.PublicChatInfo publicChatInfo = 999; - */ - public boolean hasPublicChatInfo() { - return ((bitField0_ & 0x00002000) == 0x00002000); - } - /** - * optional .signalservice.PublicChatInfo publicChatInfo = 999; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo getPublicChatInfo() { - if (publicChatInfoBuilder_ == null) { - return publicChatInfo_; - } else { - return publicChatInfoBuilder_.getMessage(); - } - } - /** - * optional .signalservice.PublicChatInfo publicChatInfo = 999; - */ - public Builder setPublicChatInfo(org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo value) { - if (publicChatInfoBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - publicChatInfo_ = value; - onChanged(); - } else { - publicChatInfoBuilder_.setMessage(value); - } - bitField0_ |= 0x00002000; - return this; - } - /** - * optional .signalservice.PublicChatInfo publicChatInfo = 999; - */ - public Builder setPublicChatInfo( - org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo.Builder builderForValue) { - if (publicChatInfoBuilder_ == null) { - publicChatInfo_ = builderForValue.build(); - onChanged(); - } else { - publicChatInfoBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00002000; - return this; - } - /** - * optional .signalservice.PublicChatInfo publicChatInfo = 999; - */ - public Builder mergePublicChatInfo(org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo value) { - if (publicChatInfoBuilder_ == null) { - if (((bitField0_ & 0x00002000) == 0x00002000) && - publicChatInfo_ != org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo.getDefaultInstance()) { - publicChatInfo_ = - org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo.newBuilder(publicChatInfo_).mergeFrom(value).buildPartial(); - } else { - publicChatInfo_ = value; - } - onChanged(); - } else { - publicChatInfoBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00002000; - return this; - } - /** - * optional .signalservice.PublicChatInfo publicChatInfo = 999; - */ - public Builder clearPublicChatInfo() { - if (publicChatInfoBuilder_ == null) { - publicChatInfo_ = org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo.getDefaultInstance(); - onChanged(); - } else { - publicChatInfoBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00002000); - return this; - } - /** - * optional .signalservice.PublicChatInfo publicChatInfo = 999; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo.Builder getPublicChatInfoBuilder() { - bitField0_ |= 0x00002000; - onChanged(); - return getPublicChatInfoFieldBuilder().getBuilder(); - } - /** - * optional .signalservice.PublicChatInfo publicChatInfo = 999; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfoOrBuilder getPublicChatInfoOrBuilder() { - if (publicChatInfoBuilder_ != null) { - return publicChatInfoBuilder_.getMessageOrBuilder(); - } else { - return publicChatInfo_; - } - } - /** - * optional .signalservice.PublicChatInfo publicChatInfo = 999; - */ - private com.google.protobuf.SingleFieldBuilder< - org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo, org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfoOrBuilder> - getPublicChatInfoFieldBuilder() { - if (publicChatInfoBuilder_ == null) { - publicChatInfoBuilder_ = new com.google.protobuf.SingleFieldBuilder< - org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo, org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfoOrBuilder>( - publicChatInfo_, - getParentForChildren(), - isClean()); - publicChatInfo_ = null; - } - return publicChatInfoBuilder_; - } - // @@protoc_insertion_point(builder_scope:signalservice.DataMessage) } @@ -24486,9 +16357,9 @@ public final class SignalServiceProtos { public interface ReceiptMessageOrBuilder extends com.google.protobuf.MessageOrBuilder { - // optional .signalservice.ReceiptMessage.Type type = 1; + // required .signalservice.ReceiptMessage.Type type = 1; /** - * optional .signalservice.ReceiptMessage.Type type = 1; + * required .signalservice.ReceiptMessage.Type type = 1; * *
      * @required
@@ -24496,7 +16367,7 @@ public final class SignalServiceProtos {
      */
     boolean hasType();
     /**
-     * optional .signalservice.ReceiptMessage.Type type = 1;
+     * required .signalservice.ReceiptMessage.Type type = 1;
      *
      * 
      * @required
@@ -24726,11 +16597,11 @@ public final class SignalServiceProtos {
     }
 
     private int bitField0_;
-    // optional .signalservice.ReceiptMessage.Type type = 1;
+    // required .signalservice.ReceiptMessage.Type type = 1;
     public static final int TYPE_FIELD_NUMBER = 1;
     private org.session.libsignal.service.internal.push.SignalServiceProtos.ReceiptMessage.Type type_;
     /**
-     * optional .signalservice.ReceiptMessage.Type type = 1;
+     * required .signalservice.ReceiptMessage.Type type = 1;
      *
      * 
      * @required
@@ -24740,7 +16611,7 @@ public final class SignalServiceProtos {
       return ((bitField0_ & 0x00000001) == 0x00000001);
     }
     /**
-     * optional .signalservice.ReceiptMessage.Type type = 1;
+     * required .signalservice.ReceiptMessage.Type type = 1;
      *
      * 
      * @required
@@ -24782,6 +16653,10 @@ public final class SignalServiceProtos {
       byte isInitialized = memoizedIsInitialized;
       if (isInitialized != -1) return isInitialized == 1;
 
+      if (!hasType()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
       memoizedIsInitialized = 1;
       return true;
     }
@@ -25008,6 +16883,10 @@ public final class SignalServiceProtos {
       }
 
       public final boolean isInitialized() {
+        if (!hasType()) {
+          
+          return false;
+        }
         return true;
       }
 
@@ -25030,10 +16909,10 @@ public final class SignalServiceProtos {
       }
       private int bitField0_;
 
-      // optional .signalservice.ReceiptMessage.Type type = 1;
+      // required .signalservice.ReceiptMessage.Type type = 1;
       private org.session.libsignal.service.internal.push.SignalServiceProtos.ReceiptMessage.Type type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.ReceiptMessage.Type.DELIVERY;
       /**
-       * optional .signalservice.ReceiptMessage.Type type = 1;
+       * required .signalservice.ReceiptMessage.Type type = 1;
        *
        * 
        * @required
@@ -25043,7 +16922,7 @@ public final class SignalServiceProtos {
         return ((bitField0_ & 0x00000001) == 0x00000001);
       }
       /**
-       * optional .signalservice.ReceiptMessage.Type type = 1;
+       * required .signalservice.ReceiptMessage.Type type = 1;
        *
        * 
        * @required
@@ -25053,7 +16932,7 @@ public final class SignalServiceProtos {
         return type_;
       }
       /**
-       * optional .signalservice.ReceiptMessage.Type type = 1;
+       * required .signalservice.ReceiptMessage.Type type = 1;
        *
        * 
        * @required
@@ -25069,7 +16948,7 @@ public final class SignalServiceProtos {
         return this;
       }
       /**
-       * optional .signalservice.ReceiptMessage.Type type = 1;
+       * required .signalservice.ReceiptMessage.Type type = 1;
        *
        * 
        * @required
@@ -25162,9 +17041,9 @@ public final class SignalServiceProtos {
   public interface AttachmentPointerOrBuilder
       extends com.google.protobuf.MessageOrBuilder {
 
-    // optional fixed64 id = 1;
+    // required fixed64 id = 1;
     /**
-     * optional fixed64 id = 1;
+     * required fixed64 id = 1;
      *
      * 
      * @required
@@ -25172,7 +17051,7 @@ public final class SignalServiceProtos {
      */
     boolean hasId();
     /**
-     * optional fixed64 id = 1;
+     * required fixed64 id = 1;
      *
      * 
      * @required
@@ -25534,11 +17413,11 @@ public final class SignalServiceProtos {
     }
 
     private int bitField0_;
-    // optional fixed64 id = 1;
+    // required fixed64 id = 1;
     public static final int ID_FIELD_NUMBER = 1;
     private long id_;
     /**
-     * optional fixed64 id = 1;
+     * required fixed64 id = 1;
      *
      * 
      * @required
@@ -25548,7 +17427,7 @@ public final class SignalServiceProtos {
       return ((bitField0_ & 0x00000001) == 0x00000001);
     }
     /**
-     * optional fixed64 id = 1;
+     * required fixed64 id = 1;
      *
      * 
      * @required
@@ -25861,6 +17740,10 @@ public final class SignalServiceProtos {
       byte isInitialized = memoizedIsInitialized;
       if (isInitialized != -1) return isInitialized == 1;
 
+      if (!hasId()) {
+        memoizedIsInitialized = 0;
+        return false;
+      }
       memoizedIsInitialized = 1;
       return true;
     }
@@ -26242,6 +18125,10 @@ public final class SignalServiceProtos {
       }
 
       public final boolean isInitialized() {
+        if (!hasId()) {
+          
+          return false;
+        }
         return true;
       }
 
@@ -26264,10 +18151,10 @@ public final class SignalServiceProtos {
       }
       private int bitField0_;
 
-      // optional fixed64 id = 1;
+      // required fixed64 id = 1;
       private long id_ ;
       /**
-       * optional fixed64 id = 1;
+       * required fixed64 id = 1;
        *
        * 
        * @required
@@ -26277,7 +18164,7 @@ public final class SignalServiceProtos {
         return ((bitField0_ & 0x00000001) == 0x00000001);
       }
       /**
-       * optional fixed64 id = 1;
+       * required fixed64 id = 1;
        *
        * 
        * @required
@@ -26287,7 +18174,7 @@ public final class SignalServiceProtos {
         return id_;
       }
       /**
-       * optional fixed64 id = 1;
+       * required fixed64 id = 1;
        *
        * 
        * @required
@@ -26300,7 +18187,7 @@ public final class SignalServiceProtos {
         return this;
       }
       /**
-       * optional fixed64 id = 1;
+       * required fixed64 id = 1;
        *
        * 
        * @required
@@ -26967,70 +18854,6 @@ public final class SignalServiceProtos {
      */
     com.google.protobuf.ByteString
         getAdminsBytes(int index);
-
-    // repeated string newMembers = 998;
-    /**
-     * repeated string newMembers = 998;
-     *
-     * 
-     * Loki - These fields are only used internally for the Android code base.
-     * This is so that we can differentiate adding/kicking.
-     * DO NOT USE WHEN SENDING MESSAGES.
-     * 
- */ - java.util.List - getNewMembersList(); - /** - * repeated string newMembers = 998; - * - *
-     * Loki - These fields are only used internally for the Android code base.
-     * This is so that we can differentiate adding/kicking.
-     * DO NOT USE WHEN SENDING MESSAGES.
-     * 
- */ - int getNewMembersCount(); - /** - * repeated string newMembers = 998; - * - *
-     * Loki - These fields are only used internally for the Android code base.
-     * This is so that we can differentiate adding/kicking.
-     * DO NOT USE WHEN SENDING MESSAGES.
-     * 
- */ - java.lang.String getNewMembers(int index); - /** - * repeated string newMembers = 998; - * - *
-     * Loki - These fields are only used internally for the Android code base.
-     * This is so that we can differentiate adding/kicking.
-     * DO NOT USE WHEN SENDING MESSAGES.
-     * 
- */ - com.google.protobuf.ByteString - getNewMembersBytes(int index); - - // repeated string removedMembers = 999; - /** - * repeated string removedMembers = 999; - */ - java.util.List - getRemovedMembersList(); - /** - * repeated string removedMembers = 999; - */ - int getRemovedMembersCount(); - /** - * repeated string removedMembers = 999; - */ - java.lang.String getRemovedMembers(int index); - /** - * repeated string removedMembers = 999; - */ - com.google.protobuf.ByteString - getRemovedMembersBytes(int index); } /** * Protobuf type {@code signalservice.GroupContext} @@ -27133,22 +18956,6 @@ public final class SignalServiceProtos { admins_.add(input.readBytes()); break; } - case 7986: { - if (!((mutable_bitField0_ & 0x00000040) == 0x00000040)) { - newMembers_ = new com.google.protobuf.LazyStringArrayList(); - mutable_bitField0_ |= 0x00000040; - } - newMembers_.add(input.readBytes()); - break; - } - case 7994: { - if (!((mutable_bitField0_ & 0x00000080) == 0x00000080)) { - removedMembers_ = new com.google.protobuf.LazyStringArrayList(); - mutable_bitField0_ |= 0x00000080; - } - removedMembers_.add(input.readBytes()); - break; - } } } } catch (com.google.protobuf.InvalidProtocolBufferException e) { @@ -27163,12 +18970,6 @@ public final class SignalServiceProtos { if (((mutable_bitField0_ & 0x00000020) == 0x00000020)) { admins_ = new com.google.protobuf.UnmodifiableLazyStringList(admins_); } - if (((mutable_bitField0_ & 0x00000040) == 0x00000040)) { - newMembers_ = new com.google.protobuf.UnmodifiableLazyStringList(newMembers_); - } - if (((mutable_bitField0_ & 0x00000080) == 0x00000080)) { - removedMembers_ = new com.google.protobuf.UnmodifiableLazyStringList(removedMembers_); - } this.unknownFields = unknownFields.build(); makeExtensionsImmutable(); } @@ -27483,90 +19284,6 @@ public final class SignalServiceProtos { return admins_.getByteString(index); } - // repeated string newMembers = 998; - public static final int NEWMEMBERS_FIELD_NUMBER = 998; - private com.google.protobuf.LazyStringList newMembers_; - /** - * repeated string newMembers = 998; - * - *
-     * Loki - These fields are only used internally for the Android code base.
-     * This is so that we can differentiate adding/kicking.
-     * DO NOT USE WHEN SENDING MESSAGES.
-     * 
- */ - public java.util.List - getNewMembersList() { - return newMembers_; - } - /** - * repeated string newMembers = 998; - * - *
-     * Loki - These fields are only used internally for the Android code base.
-     * This is so that we can differentiate adding/kicking.
-     * DO NOT USE WHEN SENDING MESSAGES.
-     * 
- */ - public int getNewMembersCount() { - return newMembers_.size(); - } - /** - * repeated string newMembers = 998; - * - *
-     * Loki - These fields are only used internally for the Android code base.
-     * This is so that we can differentiate adding/kicking.
-     * DO NOT USE WHEN SENDING MESSAGES.
-     * 
- */ - public java.lang.String getNewMembers(int index) { - return newMembers_.get(index); - } - /** - * repeated string newMembers = 998; - * - *
-     * Loki - These fields are only used internally for the Android code base.
-     * This is so that we can differentiate adding/kicking.
-     * DO NOT USE WHEN SENDING MESSAGES.
-     * 
- */ - public com.google.protobuf.ByteString - getNewMembersBytes(int index) { - return newMembers_.getByteString(index); - } - - // repeated string removedMembers = 999; - public static final int REMOVEDMEMBERS_FIELD_NUMBER = 999; - private com.google.protobuf.LazyStringList removedMembers_; - /** - * repeated string removedMembers = 999; - */ - public java.util.List - getRemovedMembersList() { - return removedMembers_; - } - /** - * repeated string removedMembers = 999; - */ - public int getRemovedMembersCount() { - return removedMembers_.size(); - } - /** - * repeated string removedMembers = 999; - */ - public java.lang.String getRemovedMembers(int index) { - return removedMembers_.get(index); - } - /** - * repeated string removedMembers = 999; - */ - public com.google.protobuf.ByteString - getRemovedMembersBytes(int index) { - return removedMembers_.getByteString(index); - } - private void initFields() { id_ = com.google.protobuf.ByteString.EMPTY; type_ = org.session.libsignal.service.internal.push.SignalServiceProtos.GroupContext.Type.UNKNOWN; @@ -27574,14 +19291,18 @@ public final class SignalServiceProtos { members_ = com.google.protobuf.LazyStringArrayList.EMPTY; avatar_ = org.session.libsignal.service.internal.push.SignalServiceProtos.AttachmentPointer.getDefaultInstance(); admins_ = com.google.protobuf.LazyStringArrayList.EMPTY; - newMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; - removedMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; } private byte memoizedIsInitialized = -1; public final boolean isInitialized() { byte isInitialized = memoizedIsInitialized; if (isInitialized != -1) return isInitialized == 1; + if (hasAvatar()) { + if (!getAvatar().isInitialized()) { + memoizedIsInitialized = 0; + return false; + } + } memoizedIsInitialized = 1; return true; } @@ -27607,12 +19328,6 @@ public final class SignalServiceProtos { for (int i = 0; i < admins_.size(); i++) { output.writeBytes(6, admins_.getByteString(i)); } - for (int i = 0; i < newMembers_.size(); i++) { - output.writeBytes(998, newMembers_.getByteString(i)); - } - for (int i = 0; i < removedMembers_.size(); i++) { - output.writeBytes(999, removedMembers_.getByteString(i)); - } getUnknownFields().writeTo(output); } @@ -27656,24 +19371,6 @@ public final class SignalServiceProtos { size += dataSize; size += 1 * getAdminsList().size(); } - { - int dataSize = 0; - for (int i = 0; i < newMembers_.size(); i++) { - dataSize += com.google.protobuf.CodedOutputStream - .computeBytesSizeNoTag(newMembers_.getByteString(i)); - } - size += dataSize; - size += 2 * getNewMembersList().size(); - } - { - int dataSize = 0; - for (int i = 0; i < removedMembers_.size(); i++) { - dataSize += com.google.protobuf.CodedOutputStream - .computeBytesSizeNoTag(removedMembers_.getByteString(i)); - } - size += dataSize; - size += 2 * getRemovedMembersList().size(); - } size += getUnknownFields().getSerializedSize(); memoizedSerializedSize = size; return size; @@ -27807,10 +19504,6 @@ public final class SignalServiceProtos { bitField0_ = (bitField0_ & ~0x00000010); admins_ = com.google.protobuf.LazyStringArrayList.EMPTY; bitField0_ = (bitField0_ & ~0x00000020); - newMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; - bitField0_ = (bitField0_ & ~0x00000040); - removedMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; - bitField0_ = (bitField0_ & ~0x00000080); return this; } @@ -27871,18 +19564,6 @@ public final class SignalServiceProtos { bitField0_ = (bitField0_ & ~0x00000020); } result.admins_ = admins_; - if (((bitField0_ & 0x00000040) == 0x00000040)) { - newMembers_ = new com.google.protobuf.UnmodifiableLazyStringList( - newMembers_); - bitField0_ = (bitField0_ & ~0x00000040); - } - result.newMembers_ = newMembers_; - if (((bitField0_ & 0x00000080) == 0x00000080)) { - removedMembers_ = new com.google.protobuf.UnmodifiableLazyStringList( - removedMembers_); - bitField0_ = (bitField0_ & ~0x00000080); - } - result.removedMembers_ = removedMembers_; result.bitField0_ = to_bitField0_; onBuilt(); return result; @@ -27933,31 +19614,17 @@ public final class SignalServiceProtos { } onChanged(); } - if (!other.newMembers_.isEmpty()) { - if (newMembers_.isEmpty()) { - newMembers_ = other.newMembers_; - bitField0_ = (bitField0_ & ~0x00000040); - } else { - ensureNewMembersIsMutable(); - newMembers_.addAll(other.newMembers_); - } - onChanged(); - } - if (!other.removedMembers_.isEmpty()) { - if (removedMembers_.isEmpty()) { - removedMembers_ = other.removedMembers_; - bitField0_ = (bitField0_ & ~0x00000080); - } else { - ensureRemovedMembersIsMutable(); - removedMembers_.addAll(other.removedMembers_); - } - onChanged(); - } this.mergeUnknownFields(other.getUnknownFields()); return this; } public final boolean isInitialized() { + if (hasAvatar()) { + if (!getAvatar().isInitialized()) { + + return false; + } + } return true; } @@ -28461,246 +20128,6 @@ public final class SignalServiceProtos { return this; } - // repeated string newMembers = 998; - private com.google.protobuf.LazyStringList newMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; - private void ensureNewMembersIsMutable() { - if (!((bitField0_ & 0x00000040) == 0x00000040)) { - newMembers_ = new com.google.protobuf.LazyStringArrayList(newMembers_); - bitField0_ |= 0x00000040; - } - } - /** - * repeated string newMembers = 998; - * - *
-       * Loki - These fields are only used internally for the Android code base.
-       * This is so that we can differentiate adding/kicking.
-       * DO NOT USE WHEN SENDING MESSAGES.
-       * 
- */ - public java.util.List - getNewMembersList() { - return java.util.Collections.unmodifiableList(newMembers_); - } - /** - * repeated string newMembers = 998; - * - *
-       * Loki - These fields are only used internally for the Android code base.
-       * This is so that we can differentiate adding/kicking.
-       * DO NOT USE WHEN SENDING MESSAGES.
-       * 
- */ - public int getNewMembersCount() { - return newMembers_.size(); - } - /** - * repeated string newMembers = 998; - * - *
-       * Loki - These fields are only used internally for the Android code base.
-       * This is so that we can differentiate adding/kicking.
-       * DO NOT USE WHEN SENDING MESSAGES.
-       * 
- */ - public java.lang.String getNewMembers(int index) { - return newMembers_.get(index); - } - /** - * repeated string newMembers = 998; - * - *
-       * Loki - These fields are only used internally for the Android code base.
-       * This is so that we can differentiate adding/kicking.
-       * DO NOT USE WHEN SENDING MESSAGES.
-       * 
- */ - public com.google.protobuf.ByteString - getNewMembersBytes(int index) { - return newMembers_.getByteString(index); - } - /** - * repeated string newMembers = 998; - * - *
-       * Loki - These fields are only used internally for the Android code base.
-       * This is so that we can differentiate adding/kicking.
-       * DO NOT USE WHEN SENDING MESSAGES.
-       * 
- */ - public Builder setNewMembers( - int index, java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - ensureNewMembersIsMutable(); - newMembers_.set(index, value); - onChanged(); - return this; - } - /** - * repeated string newMembers = 998; - * - *
-       * Loki - These fields are only used internally for the Android code base.
-       * This is so that we can differentiate adding/kicking.
-       * DO NOT USE WHEN SENDING MESSAGES.
-       * 
- */ - public Builder addNewMembers( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - ensureNewMembersIsMutable(); - newMembers_.add(value); - onChanged(); - return this; - } - /** - * repeated string newMembers = 998; - * - *
-       * Loki - These fields are only used internally for the Android code base.
-       * This is so that we can differentiate adding/kicking.
-       * DO NOT USE WHEN SENDING MESSAGES.
-       * 
- */ - public Builder addAllNewMembers( - java.lang.Iterable values) { - ensureNewMembersIsMutable(); - super.addAll(values, newMembers_); - onChanged(); - return this; - } - /** - * repeated string newMembers = 998; - * - *
-       * Loki - These fields are only used internally for the Android code base.
-       * This is so that we can differentiate adding/kicking.
-       * DO NOT USE WHEN SENDING MESSAGES.
-       * 
- */ - public Builder clearNewMembers() { - newMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; - bitField0_ = (bitField0_ & ~0x00000040); - onChanged(); - return this; - } - /** - * repeated string newMembers = 998; - * - *
-       * Loki - These fields are only used internally for the Android code base.
-       * This is so that we can differentiate adding/kicking.
-       * DO NOT USE WHEN SENDING MESSAGES.
-       * 
- */ - public Builder addNewMembersBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - ensureNewMembersIsMutable(); - newMembers_.add(value); - onChanged(); - return this; - } - - // repeated string removedMembers = 999; - private com.google.protobuf.LazyStringList removedMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; - private void ensureRemovedMembersIsMutable() { - if (!((bitField0_ & 0x00000080) == 0x00000080)) { - removedMembers_ = new com.google.protobuf.LazyStringArrayList(removedMembers_); - bitField0_ |= 0x00000080; - } - } - /** - * repeated string removedMembers = 999; - */ - public java.util.List - getRemovedMembersList() { - return java.util.Collections.unmodifiableList(removedMembers_); - } - /** - * repeated string removedMembers = 999; - */ - public int getRemovedMembersCount() { - return removedMembers_.size(); - } - /** - * repeated string removedMembers = 999; - */ - public java.lang.String getRemovedMembers(int index) { - return removedMembers_.get(index); - } - /** - * repeated string removedMembers = 999; - */ - public com.google.protobuf.ByteString - getRemovedMembersBytes(int index) { - return removedMembers_.getByteString(index); - } - /** - * repeated string removedMembers = 999; - */ - public Builder setRemovedMembers( - int index, java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - ensureRemovedMembersIsMutable(); - removedMembers_.set(index, value); - onChanged(); - return this; - } - /** - * repeated string removedMembers = 999; - */ - public Builder addRemovedMembers( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - ensureRemovedMembersIsMutable(); - removedMembers_.add(value); - onChanged(); - return this; - } - /** - * repeated string removedMembers = 999; - */ - public Builder addAllRemovedMembers( - java.lang.Iterable values) { - ensureRemovedMembersIsMutable(); - super.addAll(values, removedMembers_); - onChanged(); - return this; - } - /** - * repeated string removedMembers = 999; - */ - public Builder clearRemovedMembers() { - removedMembers_ = com.google.protobuf.LazyStringArrayList.EMPTY; - bitField0_ = (bitField0_ & ~0x00000080); - onChanged(); - return this; - } - /** - * repeated string removedMembers = 999; - */ - public Builder addRemovedMembersBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - ensureRemovedMembersIsMutable(); - removedMembers_.add(value); - onChanged(); - return this; - } - // @@protoc_insertion_point(builder_scope:signalservice.GroupContext) } @@ -28712,4487 +20139,6 @@ public final class SignalServiceProtos { // @@protoc_insertion_point(class_scope:signalservice.GroupContext) } - public interface ContactDetailsOrBuilder - extends com.google.protobuf.MessageOrBuilder { - - // optional string number = 1; - /** - * optional string number = 1; - * - *
-     * @required
-     * 
- */ - boolean hasNumber(); - /** - * optional string number = 1; - * - *
-     * @required
-     * 
- */ - java.lang.String getNumber(); - /** - * optional string number = 1; - * - *
-     * @required
-     * 
- */ - com.google.protobuf.ByteString - getNumberBytes(); - - // optional string name = 2; - /** - * optional string name = 2; - */ - boolean hasName(); - /** - * optional string name = 2; - */ - java.lang.String getName(); - /** - * optional string name = 2; - */ - com.google.protobuf.ByteString - getNameBytes(); - - // optional .signalservice.ContactDetails.Avatar avatar = 3; - /** - * optional .signalservice.ContactDetails.Avatar avatar = 3; - */ - boolean hasAvatar(); - /** - * optional .signalservice.ContactDetails.Avatar avatar = 3; - */ - org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar getAvatar(); - /** - * optional .signalservice.ContactDetails.Avatar avatar = 3; - */ - org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.AvatarOrBuilder getAvatarOrBuilder(); - - // optional string color = 4; - /** - * optional string color = 4; - */ - boolean hasColor(); - /** - * optional string color = 4; - */ - java.lang.String getColor(); - /** - * optional string color = 4; - */ - com.google.protobuf.ByteString - getColorBytes(); - - // optional bytes profileKey = 6; - /** - * optional bytes profileKey = 6; - */ - boolean hasProfileKey(); - /** - * optional bytes profileKey = 6; - */ - com.google.protobuf.ByteString getProfileKey(); - - // optional bool blocked = 7; - /** - * optional bool blocked = 7; - */ - boolean hasBlocked(); - /** - * optional bool blocked = 7; - */ - boolean getBlocked(); - - // optional uint32 expireTimer = 8; - /** - * optional uint32 expireTimer = 8; - */ - boolean hasExpireTimer(); - /** - * optional uint32 expireTimer = 8; - */ - int getExpireTimer(); - - // optional string nickname = 101; - /** - * optional string nickname = 101; - */ - boolean hasNickname(); - /** - * optional string nickname = 101; - */ - java.lang.String getNickname(); - /** - * optional string nickname = 101; - */ - com.google.protobuf.ByteString - getNicknameBytes(); - } - /** - * Protobuf type {@code signalservice.ContactDetails} - */ - public static final class ContactDetails extends - com.google.protobuf.GeneratedMessage - implements ContactDetailsOrBuilder { - // Use ContactDetails.newBuilder() to construct. - private ContactDetails(com.google.protobuf.GeneratedMessage.Builder builder) { - super(builder); - this.unknownFields = builder.getUnknownFields(); - } - private ContactDetails(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } - - private static final ContactDetails defaultInstance; - public static ContactDetails getDefaultInstance() { - return defaultInstance; - } - - public ContactDetails getDefaultInstanceForType() { - return defaultInstance; - } - - private final com.google.protobuf.UnknownFieldSet unknownFields; - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private ContactDetails( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - initFields(); - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - default: { - if (!parseUnknownField(input, unknownFields, - extensionRegistry, tag)) { - done = true; - } - break; - } - case 10: { - bitField0_ |= 0x00000001; - number_ = input.readBytes(); - break; - } - case 18: { - bitField0_ |= 0x00000002; - name_ = input.readBytes(); - break; - } - case 26: { - org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar.Builder subBuilder = null; - if (((bitField0_ & 0x00000004) == 0x00000004)) { - subBuilder = avatar_.toBuilder(); - } - avatar_ = input.readMessage(org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar.PARSER, extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(avatar_); - avatar_ = subBuilder.buildPartial(); - } - bitField0_ |= 0x00000004; - break; - } - case 34: { - bitField0_ |= 0x00000008; - color_ = input.readBytes(); - break; - } - case 50: { - bitField0_ |= 0x00000010; - profileKey_ = input.readBytes(); - break; - } - case 56: { - bitField0_ |= 0x00000020; - blocked_ = input.readBool(); - break; - } - case 64: { - bitField0_ |= 0x00000040; - expireTimer_ = input.readUInt32(); - break; - } - case 810: { - bitField0_ |= 0x00000080; - nickname_ = input.readBytes(); - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e.getMessage()).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_ContactDetails_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_ContactDetails_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.class, org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Builder.class); - } - - public static com.google.protobuf.Parser PARSER = - new com.google.protobuf.AbstractParser() { - public ContactDetails parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new ContactDetails(input, extensionRegistry); - } - }; - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - public interface AvatarOrBuilder - extends com.google.protobuf.MessageOrBuilder { - - // optional string contentType = 1; - /** - * optional string contentType = 1; - */ - boolean hasContentType(); - /** - * optional string contentType = 1; - */ - java.lang.String getContentType(); - /** - * optional string contentType = 1; - */ - com.google.protobuf.ByteString - getContentTypeBytes(); - - // optional uint32 length = 2; - /** - * optional uint32 length = 2; - */ - boolean hasLength(); - /** - * optional uint32 length = 2; - */ - int getLength(); - } - /** - * Protobuf type {@code signalservice.ContactDetails.Avatar} - */ - public static final class Avatar extends - com.google.protobuf.GeneratedMessage - implements AvatarOrBuilder { - // Use Avatar.newBuilder() to construct. - private Avatar(com.google.protobuf.GeneratedMessage.Builder builder) { - super(builder); - this.unknownFields = builder.getUnknownFields(); - } - private Avatar(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } - - private static final Avatar defaultInstance; - public static Avatar getDefaultInstance() { - return defaultInstance; - } - - public Avatar getDefaultInstanceForType() { - return defaultInstance; - } - - private final com.google.protobuf.UnknownFieldSet unknownFields; - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private Avatar( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - initFields(); - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - default: { - if (!parseUnknownField(input, unknownFields, - extensionRegistry, tag)) { - done = true; - } - break; - } - case 10: { - bitField0_ |= 0x00000001; - contentType_ = input.readBytes(); - break; - } - case 16: { - bitField0_ |= 0x00000002; - length_ = input.readUInt32(); - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e.getMessage()).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_ContactDetails_Avatar_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_ContactDetails_Avatar_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar.class, org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar.Builder.class); - } - - public static com.google.protobuf.Parser PARSER = - new com.google.protobuf.AbstractParser() { - public Avatar parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new Avatar(input, extensionRegistry); - } - }; - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - private int bitField0_; - // optional string contentType = 1; - public static final int CONTENTTYPE_FIELD_NUMBER = 1; - private java.lang.Object contentType_; - /** - * optional string contentType = 1; - */ - public boolean hasContentType() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional string contentType = 1; - */ - public java.lang.String getContentType() { - java.lang.Object ref = contentType_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - contentType_ = s; - } - return s; - } - } - /** - * optional string contentType = 1; - */ - public com.google.protobuf.ByteString - getContentTypeBytes() { - java.lang.Object ref = contentType_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - contentType_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - // optional uint32 length = 2; - public static final int LENGTH_FIELD_NUMBER = 2; - private int length_; - /** - * optional uint32 length = 2; - */ - public boolean hasLength() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional uint32 length = 2; - */ - public int getLength() { - return length_; - } - - private void initFields() { - contentType_ = ""; - length_ = 0; - } - private byte memoizedIsInitialized = -1; - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized != -1) return isInitialized == 1; - - memoizedIsInitialized = 1; - return true; - } - - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - getSerializedSize(); - if (((bitField0_ & 0x00000001) == 0x00000001)) { - output.writeBytes(1, getContentTypeBytes()); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - output.writeUInt32(2, length_); - } - getUnknownFields().writeTo(output); - } - - private int memoizedSerializedSize = -1; - public int getSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (((bitField0_ & 0x00000001) == 0x00000001)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, getContentTypeBytes()); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - size += com.google.protobuf.CodedOutputStream - .computeUInt32Size(2, length_); - } - size += getUnknownFields().getSerializedSize(); - memoizedSerializedSize = size; - return size; - } - - private static final long serialVersionUID = 0L; - @java.lang.Override - protected java.lang.Object writeReplace() - throws java.io.ObjectStreamException { - return super.writeReplace(); - } - - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar parseFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - - public static Builder newBuilder() { return Builder.create(); } - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar prototype) { - return newBuilder().mergeFrom(prototype); - } - public Builder toBuilder() { return newBuilder(this); } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code signalservice.ContactDetails.Avatar} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessage.Builder - implements org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.AvatarOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_ContactDetails_Avatar_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_ContactDetails_Avatar_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar.class, org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar.Builder.class); - } - - // Construct using org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { - } - } - private static Builder create() { - return new Builder(); - } - - public Builder clear() { - super.clear(); - contentType_ = ""; - bitField0_ = (bitField0_ & ~0x00000001); - length_ = 0; - bitField0_ = (bitField0_ & ~0x00000002); - return this; - } - - public Builder clone() { - return create().mergeFrom(buildPartial()); - } - - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_ContactDetails_Avatar_descriptor; - } - - public org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar getDefaultInstanceForType() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar.getDefaultInstance(); - } - - public org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar build() { - org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - public org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar buildPartial() { - org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar result = new org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) == 0x00000001)) { - to_bitField0_ |= 0x00000001; - } - result.contentType_ = contentType_; - if (((from_bitField0_ & 0x00000002) == 0x00000002)) { - to_bitField0_ |= 0x00000002; - } - result.length_ = length_; - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar) { - return mergeFrom((org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar other) { - if (other == org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar.getDefaultInstance()) return this; - if (other.hasContentType()) { - bitField0_ |= 0x00000001; - contentType_ = other.contentType_; - onChanged(); - } - if (other.hasLength()) { - setLength(other.getLength()); - } - this.mergeUnknownFields(other.getUnknownFields()); - return this; - } - - public final boolean isInitialized() { - return true; - } - - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar) e.getUnfinishedMessage(); - throw e; - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - // optional string contentType = 1; - private java.lang.Object contentType_ = ""; - /** - * optional string contentType = 1; - */ - public boolean hasContentType() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional string contentType = 1; - */ - public java.lang.String getContentType() { - java.lang.Object ref = contentType_; - if (!(ref instanceof java.lang.String)) { - java.lang.String s = ((com.google.protobuf.ByteString) ref) - .toStringUtf8(); - contentType_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * optional string contentType = 1; - */ - public com.google.protobuf.ByteString - getContentTypeBytes() { - java.lang.Object ref = contentType_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - contentType_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * optional string contentType = 1; - */ - public Builder setContentType( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - contentType_ = value; - onChanged(); - return this; - } - /** - * optional string contentType = 1; - */ - public Builder clearContentType() { - bitField0_ = (bitField0_ & ~0x00000001); - contentType_ = getDefaultInstance().getContentType(); - onChanged(); - return this; - } - /** - * optional string contentType = 1; - */ - public Builder setContentTypeBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - contentType_ = value; - onChanged(); - return this; - } - - // optional uint32 length = 2; - private int length_ ; - /** - * optional uint32 length = 2; - */ - public boolean hasLength() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional uint32 length = 2; - */ - public int getLength() { - return length_; - } - /** - * optional uint32 length = 2; - */ - public Builder setLength(int value) { - bitField0_ |= 0x00000002; - length_ = value; - onChanged(); - return this; - } - /** - * optional uint32 length = 2; - */ - public Builder clearLength() { - bitField0_ = (bitField0_ & ~0x00000002); - length_ = 0; - onChanged(); - return this; - } - - // @@protoc_insertion_point(builder_scope:signalservice.ContactDetails.Avatar) - } - - static { - defaultInstance = new Avatar(true); - defaultInstance.initFields(); - } - - // @@protoc_insertion_point(class_scope:signalservice.ContactDetails.Avatar) - } - - private int bitField0_; - // optional string number = 1; - public static final int NUMBER_FIELD_NUMBER = 1; - private java.lang.Object number_; - /** - * optional string number = 1; - * - *
-     * @required
-     * 
- */ - public boolean hasNumber() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional string number = 1; - * - *
-     * @required
-     * 
- */ - public java.lang.String getNumber() { - java.lang.Object ref = number_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - number_ = s; - } - return s; - } - } - /** - * optional string number = 1; - * - *
-     * @required
-     * 
- */ - public com.google.protobuf.ByteString - getNumberBytes() { - java.lang.Object ref = number_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - number_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - // optional string name = 2; - public static final int NAME_FIELD_NUMBER = 2; - private java.lang.Object name_; - /** - * optional string name = 2; - */ - public boolean hasName() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional string name = 2; - */ - public java.lang.String getName() { - java.lang.Object ref = name_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - name_ = s; - } - return s; - } - } - /** - * optional string name = 2; - */ - public com.google.protobuf.ByteString - getNameBytes() { - java.lang.Object ref = name_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - name_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - // optional .signalservice.ContactDetails.Avatar avatar = 3; - public static final int AVATAR_FIELD_NUMBER = 3; - private org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar avatar_; - /** - * optional .signalservice.ContactDetails.Avatar avatar = 3; - */ - public boolean hasAvatar() { - return ((bitField0_ & 0x00000004) == 0x00000004); - } - /** - * optional .signalservice.ContactDetails.Avatar avatar = 3; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar getAvatar() { - return avatar_; - } - /** - * optional .signalservice.ContactDetails.Avatar avatar = 3; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.AvatarOrBuilder getAvatarOrBuilder() { - return avatar_; - } - - // optional string color = 4; - public static final int COLOR_FIELD_NUMBER = 4; - private java.lang.Object color_; - /** - * optional string color = 4; - */ - public boolean hasColor() { - return ((bitField0_ & 0x00000008) == 0x00000008); - } - /** - * optional string color = 4; - */ - public java.lang.String getColor() { - java.lang.Object ref = color_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - color_ = s; - } - return s; - } - } - /** - * optional string color = 4; - */ - public com.google.protobuf.ByteString - getColorBytes() { - java.lang.Object ref = color_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - color_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - // optional bytes profileKey = 6; - public static final int PROFILEKEY_FIELD_NUMBER = 6; - private com.google.protobuf.ByteString profileKey_; - /** - * optional bytes profileKey = 6; - */ - public boolean hasProfileKey() { - return ((bitField0_ & 0x00000010) == 0x00000010); - } - /** - * optional bytes profileKey = 6; - */ - public com.google.protobuf.ByteString getProfileKey() { - return profileKey_; - } - - // optional bool blocked = 7; - public static final int BLOCKED_FIELD_NUMBER = 7; - private boolean blocked_; - /** - * optional bool blocked = 7; - */ - public boolean hasBlocked() { - return ((bitField0_ & 0x00000020) == 0x00000020); - } - /** - * optional bool blocked = 7; - */ - public boolean getBlocked() { - return blocked_; - } - - // optional uint32 expireTimer = 8; - public static final int EXPIRETIMER_FIELD_NUMBER = 8; - private int expireTimer_; - /** - * optional uint32 expireTimer = 8; - */ - public boolean hasExpireTimer() { - return ((bitField0_ & 0x00000040) == 0x00000040); - } - /** - * optional uint32 expireTimer = 8; - */ - public int getExpireTimer() { - return expireTimer_; - } - - // optional string nickname = 101; - public static final int NICKNAME_FIELD_NUMBER = 101; - private java.lang.Object nickname_; - /** - * optional string nickname = 101; - */ - public boolean hasNickname() { - return ((bitField0_ & 0x00000080) == 0x00000080); - } - /** - * optional string nickname = 101; - */ - public java.lang.String getNickname() { - java.lang.Object ref = nickname_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - nickname_ = s; - } - return s; - } - } - /** - * optional string nickname = 101; - */ - public com.google.protobuf.ByteString - getNicknameBytes() { - java.lang.Object ref = nickname_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - nickname_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - private void initFields() { - number_ = ""; - name_ = ""; - avatar_ = org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar.getDefaultInstance(); - color_ = ""; - profileKey_ = com.google.protobuf.ByteString.EMPTY; - blocked_ = false; - expireTimer_ = 0; - nickname_ = ""; - } - private byte memoizedIsInitialized = -1; - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized != -1) return isInitialized == 1; - - memoizedIsInitialized = 1; - return true; - } - - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - getSerializedSize(); - if (((bitField0_ & 0x00000001) == 0x00000001)) { - output.writeBytes(1, getNumberBytes()); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - output.writeBytes(2, getNameBytes()); - } - if (((bitField0_ & 0x00000004) == 0x00000004)) { - output.writeMessage(3, avatar_); - } - if (((bitField0_ & 0x00000008) == 0x00000008)) { - output.writeBytes(4, getColorBytes()); - } - if (((bitField0_ & 0x00000010) == 0x00000010)) { - output.writeBytes(6, profileKey_); - } - if (((bitField0_ & 0x00000020) == 0x00000020)) { - output.writeBool(7, blocked_); - } - if (((bitField0_ & 0x00000040) == 0x00000040)) { - output.writeUInt32(8, expireTimer_); - } - if (((bitField0_ & 0x00000080) == 0x00000080)) { - output.writeBytes(101, getNicknameBytes()); - } - getUnknownFields().writeTo(output); - } - - private int memoizedSerializedSize = -1; - public int getSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (((bitField0_ & 0x00000001) == 0x00000001)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, getNumberBytes()); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(2, getNameBytes()); - } - if (((bitField0_ & 0x00000004) == 0x00000004)) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(3, avatar_); - } - if (((bitField0_ & 0x00000008) == 0x00000008)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(4, getColorBytes()); - } - if (((bitField0_ & 0x00000010) == 0x00000010)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(6, profileKey_); - } - if (((bitField0_ & 0x00000020) == 0x00000020)) { - size += com.google.protobuf.CodedOutputStream - .computeBoolSize(7, blocked_); - } - if (((bitField0_ & 0x00000040) == 0x00000040)) { - size += com.google.protobuf.CodedOutputStream - .computeUInt32Size(8, expireTimer_); - } - if (((bitField0_ & 0x00000080) == 0x00000080)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(101, getNicknameBytes()); - } - size += getUnknownFields().getSerializedSize(); - memoizedSerializedSize = size; - return size; - } - - private static final long serialVersionUID = 0L; - @java.lang.Override - protected java.lang.Object writeReplace() - throws java.io.ObjectStreamException { - return super.writeReplace(); - } - - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails parseFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - - public static Builder newBuilder() { return Builder.create(); } - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails prototype) { - return newBuilder().mergeFrom(prototype); - } - public Builder toBuilder() { return newBuilder(this); } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code signalservice.ContactDetails} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessage.Builder - implements org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetailsOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_ContactDetails_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_ContactDetails_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.class, org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Builder.class); - } - - // Construct using org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { - getAvatarFieldBuilder(); - } - } - private static Builder create() { - return new Builder(); - } - - public Builder clear() { - super.clear(); - number_ = ""; - bitField0_ = (bitField0_ & ~0x00000001); - name_ = ""; - bitField0_ = (bitField0_ & ~0x00000002); - if (avatarBuilder_ == null) { - avatar_ = org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar.getDefaultInstance(); - } else { - avatarBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000004); - color_ = ""; - bitField0_ = (bitField0_ & ~0x00000008); - profileKey_ = com.google.protobuf.ByteString.EMPTY; - bitField0_ = (bitField0_ & ~0x00000010); - blocked_ = false; - bitField0_ = (bitField0_ & ~0x00000020); - expireTimer_ = 0; - bitField0_ = (bitField0_ & ~0x00000040); - nickname_ = ""; - bitField0_ = (bitField0_ & ~0x00000080); - return this; - } - - public Builder clone() { - return create().mergeFrom(buildPartial()); - } - - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_ContactDetails_descriptor; - } - - public org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails getDefaultInstanceForType() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.getDefaultInstance(); - } - - public org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails build() { - org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - public org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails buildPartial() { - org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails result = new org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) == 0x00000001)) { - to_bitField0_ |= 0x00000001; - } - result.number_ = number_; - if (((from_bitField0_ & 0x00000002) == 0x00000002)) { - to_bitField0_ |= 0x00000002; - } - result.name_ = name_; - if (((from_bitField0_ & 0x00000004) == 0x00000004)) { - to_bitField0_ |= 0x00000004; - } - if (avatarBuilder_ == null) { - result.avatar_ = avatar_; - } else { - result.avatar_ = avatarBuilder_.build(); - } - if (((from_bitField0_ & 0x00000008) == 0x00000008)) { - to_bitField0_ |= 0x00000008; - } - result.color_ = color_; - if (((from_bitField0_ & 0x00000010) == 0x00000010)) { - to_bitField0_ |= 0x00000010; - } - result.profileKey_ = profileKey_; - if (((from_bitField0_ & 0x00000020) == 0x00000020)) { - to_bitField0_ |= 0x00000020; - } - result.blocked_ = blocked_; - if (((from_bitField0_ & 0x00000040) == 0x00000040)) { - to_bitField0_ |= 0x00000040; - } - result.expireTimer_ = expireTimer_; - if (((from_bitField0_ & 0x00000080) == 0x00000080)) { - to_bitField0_ |= 0x00000080; - } - result.nickname_ = nickname_; - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails) { - return mergeFrom((org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails other) { - if (other == org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.getDefaultInstance()) return this; - if (other.hasNumber()) { - bitField0_ |= 0x00000001; - number_ = other.number_; - onChanged(); - } - if (other.hasName()) { - bitField0_ |= 0x00000002; - name_ = other.name_; - onChanged(); - } - if (other.hasAvatar()) { - mergeAvatar(other.getAvatar()); - } - if (other.hasColor()) { - bitField0_ |= 0x00000008; - color_ = other.color_; - onChanged(); - } - if (other.hasProfileKey()) { - setProfileKey(other.getProfileKey()); - } - if (other.hasBlocked()) { - setBlocked(other.getBlocked()); - } - if (other.hasExpireTimer()) { - setExpireTimer(other.getExpireTimer()); - } - if (other.hasNickname()) { - bitField0_ |= 0x00000080; - nickname_ = other.nickname_; - onChanged(); - } - this.mergeUnknownFields(other.getUnknownFields()); - return this; - } - - public final boolean isInitialized() { - return true; - } - - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails) e.getUnfinishedMessage(); - throw e; - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - // optional string number = 1; - private java.lang.Object number_ = ""; - /** - * optional string number = 1; - * - *
-       * @required
-       * 
- */ - public boolean hasNumber() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional string number = 1; - * - *
-       * @required
-       * 
- */ - public java.lang.String getNumber() { - java.lang.Object ref = number_; - if (!(ref instanceof java.lang.String)) { - java.lang.String s = ((com.google.protobuf.ByteString) ref) - .toStringUtf8(); - number_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * optional string number = 1; - * - *
-       * @required
-       * 
- */ - public com.google.protobuf.ByteString - getNumberBytes() { - java.lang.Object ref = number_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - number_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * optional string number = 1; - * - *
-       * @required
-       * 
- */ - public Builder setNumber( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - number_ = value; - onChanged(); - return this; - } - /** - * optional string number = 1; - * - *
-       * @required
-       * 
- */ - public Builder clearNumber() { - bitField0_ = (bitField0_ & ~0x00000001); - number_ = getDefaultInstance().getNumber(); - onChanged(); - return this; - } - /** - * optional string number = 1; - * - *
-       * @required
-       * 
- */ - public Builder setNumberBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - number_ = value; - onChanged(); - return this; - } - - // optional string name = 2; - private java.lang.Object name_ = ""; - /** - * optional string name = 2; - */ - public boolean hasName() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional string name = 2; - */ - public java.lang.String getName() { - java.lang.Object ref = name_; - if (!(ref instanceof java.lang.String)) { - java.lang.String s = ((com.google.protobuf.ByteString) ref) - .toStringUtf8(); - name_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * optional string name = 2; - */ - public com.google.protobuf.ByteString - getNameBytes() { - java.lang.Object ref = name_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - name_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * optional string name = 2; - */ - public Builder setName( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000002; - name_ = value; - onChanged(); - return this; - } - /** - * optional string name = 2; - */ - public Builder clearName() { - bitField0_ = (bitField0_ & ~0x00000002); - name_ = getDefaultInstance().getName(); - onChanged(); - return this; - } - /** - * optional string name = 2; - */ - public Builder setNameBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000002; - name_ = value; - onChanged(); - return this; - } - - // optional .signalservice.ContactDetails.Avatar avatar = 3; - private org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar avatar_ = org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar.getDefaultInstance(); - private com.google.protobuf.SingleFieldBuilder< - org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar, org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.AvatarOrBuilder> avatarBuilder_; - /** - * optional .signalservice.ContactDetails.Avatar avatar = 3; - */ - public boolean hasAvatar() { - return ((bitField0_ & 0x00000004) == 0x00000004); - } - /** - * optional .signalservice.ContactDetails.Avatar avatar = 3; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar getAvatar() { - if (avatarBuilder_ == null) { - return avatar_; - } else { - return avatarBuilder_.getMessage(); - } - } - /** - * optional .signalservice.ContactDetails.Avatar avatar = 3; - */ - public Builder setAvatar(org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar value) { - if (avatarBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - avatar_ = value; - onChanged(); - } else { - avatarBuilder_.setMessage(value); - } - bitField0_ |= 0x00000004; - return this; - } - /** - * optional .signalservice.ContactDetails.Avatar avatar = 3; - */ - public Builder setAvatar( - org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar.Builder builderForValue) { - if (avatarBuilder_ == null) { - avatar_ = builderForValue.build(); - onChanged(); - } else { - avatarBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000004; - return this; - } - /** - * optional .signalservice.ContactDetails.Avatar avatar = 3; - */ - public Builder mergeAvatar(org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar value) { - if (avatarBuilder_ == null) { - if (((bitField0_ & 0x00000004) == 0x00000004) && - avatar_ != org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar.getDefaultInstance()) { - avatar_ = - org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar.newBuilder(avatar_).mergeFrom(value).buildPartial(); - } else { - avatar_ = value; - } - onChanged(); - } else { - avatarBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000004; - return this; - } - /** - * optional .signalservice.ContactDetails.Avatar avatar = 3; - */ - public Builder clearAvatar() { - if (avatarBuilder_ == null) { - avatar_ = org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar.getDefaultInstance(); - onChanged(); - } else { - avatarBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000004); - return this; - } - /** - * optional .signalservice.ContactDetails.Avatar avatar = 3; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar.Builder getAvatarBuilder() { - bitField0_ |= 0x00000004; - onChanged(); - return getAvatarFieldBuilder().getBuilder(); - } - /** - * optional .signalservice.ContactDetails.Avatar avatar = 3; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.AvatarOrBuilder getAvatarOrBuilder() { - if (avatarBuilder_ != null) { - return avatarBuilder_.getMessageOrBuilder(); - } else { - return avatar_; - } - } - /** - * optional .signalservice.ContactDetails.Avatar avatar = 3; - */ - private com.google.protobuf.SingleFieldBuilder< - org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar, org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.AvatarOrBuilder> - getAvatarFieldBuilder() { - if (avatarBuilder_ == null) { - avatarBuilder_ = new com.google.protobuf.SingleFieldBuilder< - org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar, org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.Avatar.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.ContactDetails.AvatarOrBuilder>( - avatar_, - getParentForChildren(), - isClean()); - avatar_ = null; - } - return avatarBuilder_; - } - - // optional string color = 4; - private java.lang.Object color_ = ""; - /** - * optional string color = 4; - */ - public boolean hasColor() { - return ((bitField0_ & 0x00000008) == 0x00000008); - } - /** - * optional string color = 4; - */ - public java.lang.String getColor() { - java.lang.Object ref = color_; - if (!(ref instanceof java.lang.String)) { - java.lang.String s = ((com.google.protobuf.ByteString) ref) - .toStringUtf8(); - color_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * optional string color = 4; - */ - public com.google.protobuf.ByteString - getColorBytes() { - java.lang.Object ref = color_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - color_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * optional string color = 4; - */ - public Builder setColor( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000008; - color_ = value; - onChanged(); - return this; - } - /** - * optional string color = 4; - */ - public Builder clearColor() { - bitField0_ = (bitField0_ & ~0x00000008); - color_ = getDefaultInstance().getColor(); - onChanged(); - return this; - } - /** - * optional string color = 4; - */ - public Builder setColorBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000008; - color_ = value; - onChanged(); - return this; - } - - // optional bytes profileKey = 6; - private com.google.protobuf.ByteString profileKey_ = com.google.protobuf.ByteString.EMPTY; - /** - * optional bytes profileKey = 6; - */ - public boolean hasProfileKey() { - return ((bitField0_ & 0x00000010) == 0x00000010); - } - /** - * optional bytes profileKey = 6; - */ - public com.google.protobuf.ByteString getProfileKey() { - return profileKey_; - } - /** - * optional bytes profileKey = 6; - */ - public Builder setProfileKey(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000010; - profileKey_ = value; - onChanged(); - return this; - } - /** - * optional bytes profileKey = 6; - */ - public Builder clearProfileKey() { - bitField0_ = (bitField0_ & ~0x00000010); - profileKey_ = getDefaultInstance().getProfileKey(); - onChanged(); - return this; - } - - // optional bool blocked = 7; - private boolean blocked_ ; - /** - * optional bool blocked = 7; - */ - public boolean hasBlocked() { - return ((bitField0_ & 0x00000020) == 0x00000020); - } - /** - * optional bool blocked = 7; - */ - public boolean getBlocked() { - return blocked_; - } - /** - * optional bool blocked = 7; - */ - public Builder setBlocked(boolean value) { - bitField0_ |= 0x00000020; - blocked_ = value; - onChanged(); - return this; - } - /** - * optional bool blocked = 7; - */ - public Builder clearBlocked() { - bitField0_ = (bitField0_ & ~0x00000020); - blocked_ = false; - onChanged(); - return this; - } - - // optional uint32 expireTimer = 8; - private int expireTimer_ ; - /** - * optional uint32 expireTimer = 8; - */ - public boolean hasExpireTimer() { - return ((bitField0_ & 0x00000040) == 0x00000040); - } - /** - * optional uint32 expireTimer = 8; - */ - public int getExpireTimer() { - return expireTimer_; - } - /** - * optional uint32 expireTimer = 8; - */ - public Builder setExpireTimer(int value) { - bitField0_ |= 0x00000040; - expireTimer_ = value; - onChanged(); - return this; - } - /** - * optional uint32 expireTimer = 8; - */ - public Builder clearExpireTimer() { - bitField0_ = (bitField0_ & ~0x00000040); - expireTimer_ = 0; - onChanged(); - return this; - } - - // optional string nickname = 101; - private java.lang.Object nickname_ = ""; - /** - * optional string nickname = 101; - */ - public boolean hasNickname() { - return ((bitField0_ & 0x00000080) == 0x00000080); - } - /** - * optional string nickname = 101; - */ - public java.lang.String getNickname() { - java.lang.Object ref = nickname_; - if (!(ref instanceof java.lang.String)) { - java.lang.String s = ((com.google.protobuf.ByteString) ref) - .toStringUtf8(); - nickname_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * optional string nickname = 101; - */ - public com.google.protobuf.ByteString - getNicknameBytes() { - java.lang.Object ref = nickname_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - nickname_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * optional string nickname = 101; - */ - public Builder setNickname( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000080; - nickname_ = value; - onChanged(); - return this; - } - /** - * optional string nickname = 101; - */ - public Builder clearNickname() { - bitField0_ = (bitField0_ & ~0x00000080); - nickname_ = getDefaultInstance().getNickname(); - onChanged(); - return this; - } - /** - * optional string nickname = 101; - */ - public Builder setNicknameBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000080; - nickname_ = value; - onChanged(); - return this; - } - - // @@protoc_insertion_point(builder_scope:signalservice.ContactDetails) - } - - static { - defaultInstance = new ContactDetails(true); - defaultInstance.initFields(); - } - - // @@protoc_insertion_point(class_scope:signalservice.ContactDetails) - } - - public interface GroupDetailsOrBuilder - extends com.google.protobuf.MessageOrBuilder { - - // optional bytes id = 1; - /** - * optional bytes id = 1; - * - *
-     * @required
-     * 
- */ - boolean hasId(); - /** - * optional bytes id = 1; - * - *
-     * @required
-     * 
- */ - com.google.protobuf.ByteString getId(); - - // optional string name = 2; - /** - * optional string name = 2; - */ - boolean hasName(); - /** - * optional string name = 2; - */ - java.lang.String getName(); - /** - * optional string name = 2; - */ - com.google.protobuf.ByteString - getNameBytes(); - - // repeated string members = 3; - /** - * repeated string members = 3; - */ - java.util.List - getMembersList(); - /** - * repeated string members = 3; - */ - int getMembersCount(); - /** - * repeated string members = 3; - */ - java.lang.String getMembers(int index); - /** - * repeated string members = 3; - */ - com.google.protobuf.ByteString - getMembersBytes(int index); - - // optional .signalservice.GroupDetails.Avatar avatar = 4; - /** - * optional .signalservice.GroupDetails.Avatar avatar = 4; - */ - boolean hasAvatar(); - /** - * optional .signalservice.GroupDetails.Avatar avatar = 4; - */ - org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar getAvatar(); - /** - * optional .signalservice.GroupDetails.Avatar avatar = 4; - */ - org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.AvatarOrBuilder getAvatarOrBuilder(); - - // optional bool active = 5 [default = true]; - /** - * optional bool active = 5 [default = true]; - */ - boolean hasActive(); - /** - * optional bool active = 5 [default = true]; - */ - boolean getActive(); - - // optional uint32 expireTimer = 6; - /** - * optional uint32 expireTimer = 6; - */ - boolean hasExpireTimer(); - /** - * optional uint32 expireTimer = 6; - */ - int getExpireTimer(); - - // optional string color = 7; - /** - * optional string color = 7; - */ - boolean hasColor(); - /** - * optional string color = 7; - */ - java.lang.String getColor(); - /** - * optional string color = 7; - */ - com.google.protobuf.ByteString - getColorBytes(); - - // optional bool blocked = 8; - /** - * optional bool blocked = 8; - */ - boolean hasBlocked(); - /** - * optional bool blocked = 8; - */ - boolean getBlocked(); - - // repeated string admins = 9; - /** - * repeated string admins = 9; - */ - java.util.List - getAdminsList(); - /** - * repeated string admins = 9; - */ - int getAdminsCount(); - /** - * repeated string admins = 9; - */ - java.lang.String getAdmins(int index); - /** - * repeated string admins = 9; - */ - com.google.protobuf.ByteString - getAdminsBytes(int index); - } - /** - * Protobuf type {@code signalservice.GroupDetails} - */ - public static final class GroupDetails extends - com.google.protobuf.GeneratedMessage - implements GroupDetailsOrBuilder { - // Use GroupDetails.newBuilder() to construct. - private GroupDetails(com.google.protobuf.GeneratedMessage.Builder builder) { - super(builder); - this.unknownFields = builder.getUnknownFields(); - } - private GroupDetails(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } - - private static final GroupDetails defaultInstance; - public static GroupDetails getDefaultInstance() { - return defaultInstance; - } - - public GroupDetails getDefaultInstanceForType() { - return defaultInstance; - } - - private final com.google.protobuf.UnknownFieldSet unknownFields; - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private GroupDetails( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - initFields(); - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - default: { - if (!parseUnknownField(input, unknownFields, - extensionRegistry, tag)) { - done = true; - } - break; - } - case 10: { - bitField0_ |= 0x00000001; - id_ = input.readBytes(); - break; - } - case 18: { - bitField0_ |= 0x00000002; - name_ = input.readBytes(); - break; - } - case 26: { - if (!((mutable_bitField0_ & 0x00000004) == 0x00000004)) { - members_ = new com.google.protobuf.LazyStringArrayList(); - mutable_bitField0_ |= 0x00000004; - } - members_.add(input.readBytes()); - break; - } - case 34: { - org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar.Builder subBuilder = null; - if (((bitField0_ & 0x00000004) == 0x00000004)) { - subBuilder = avatar_.toBuilder(); - } - avatar_ = input.readMessage(org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar.PARSER, extensionRegistry); - if (subBuilder != null) { - subBuilder.mergeFrom(avatar_); - avatar_ = subBuilder.buildPartial(); - } - bitField0_ |= 0x00000004; - break; - } - case 40: { - bitField0_ |= 0x00000008; - active_ = input.readBool(); - break; - } - case 48: { - bitField0_ |= 0x00000010; - expireTimer_ = input.readUInt32(); - break; - } - case 58: { - bitField0_ |= 0x00000020; - color_ = input.readBytes(); - break; - } - case 64: { - bitField0_ |= 0x00000040; - blocked_ = input.readBool(); - break; - } - case 74: { - if (!((mutable_bitField0_ & 0x00000100) == 0x00000100)) { - admins_ = new com.google.protobuf.LazyStringArrayList(); - mutable_bitField0_ |= 0x00000100; - } - admins_.add(input.readBytes()); - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e.getMessage()).setUnfinishedMessage(this); - } finally { - if (((mutable_bitField0_ & 0x00000004) == 0x00000004)) { - members_ = new com.google.protobuf.UnmodifiableLazyStringList(members_); - } - if (((mutable_bitField0_ & 0x00000100) == 0x00000100)) { - admins_ = new com.google.protobuf.UnmodifiableLazyStringList(admins_); - } - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_GroupDetails_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_GroupDetails_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.class, org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Builder.class); - } - - public static com.google.protobuf.Parser PARSER = - new com.google.protobuf.AbstractParser() { - public GroupDetails parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new GroupDetails(input, extensionRegistry); - } - }; - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - public interface AvatarOrBuilder - extends com.google.protobuf.MessageOrBuilder { - - // optional string contentType = 1; - /** - * optional string contentType = 1; - */ - boolean hasContentType(); - /** - * optional string contentType = 1; - */ - java.lang.String getContentType(); - /** - * optional string contentType = 1; - */ - com.google.protobuf.ByteString - getContentTypeBytes(); - - // optional uint32 length = 2; - /** - * optional uint32 length = 2; - */ - boolean hasLength(); - /** - * optional uint32 length = 2; - */ - int getLength(); - } - /** - * Protobuf type {@code signalservice.GroupDetails.Avatar} - */ - public static final class Avatar extends - com.google.protobuf.GeneratedMessage - implements AvatarOrBuilder { - // Use Avatar.newBuilder() to construct. - private Avatar(com.google.protobuf.GeneratedMessage.Builder builder) { - super(builder); - this.unknownFields = builder.getUnknownFields(); - } - private Avatar(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } - - private static final Avatar defaultInstance; - public static Avatar getDefaultInstance() { - return defaultInstance; - } - - public Avatar getDefaultInstanceForType() { - return defaultInstance; - } - - private final com.google.protobuf.UnknownFieldSet unknownFields; - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private Avatar( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - initFields(); - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - default: { - if (!parseUnknownField(input, unknownFields, - extensionRegistry, tag)) { - done = true; - } - break; - } - case 10: { - bitField0_ |= 0x00000001; - contentType_ = input.readBytes(); - break; - } - case 16: { - bitField0_ |= 0x00000002; - length_ = input.readUInt32(); - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e.getMessage()).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_GroupDetails_Avatar_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_GroupDetails_Avatar_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar.class, org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar.Builder.class); - } - - public static com.google.protobuf.Parser PARSER = - new com.google.protobuf.AbstractParser() { - public Avatar parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new Avatar(input, extensionRegistry); - } - }; - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - private int bitField0_; - // optional string contentType = 1; - public static final int CONTENTTYPE_FIELD_NUMBER = 1; - private java.lang.Object contentType_; - /** - * optional string contentType = 1; - */ - public boolean hasContentType() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional string contentType = 1; - */ - public java.lang.String getContentType() { - java.lang.Object ref = contentType_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - contentType_ = s; - } - return s; - } - } - /** - * optional string contentType = 1; - */ - public com.google.protobuf.ByteString - getContentTypeBytes() { - java.lang.Object ref = contentType_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - contentType_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - // optional uint32 length = 2; - public static final int LENGTH_FIELD_NUMBER = 2; - private int length_; - /** - * optional uint32 length = 2; - */ - public boolean hasLength() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional uint32 length = 2; - */ - public int getLength() { - return length_; - } - - private void initFields() { - contentType_ = ""; - length_ = 0; - } - private byte memoizedIsInitialized = -1; - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized != -1) return isInitialized == 1; - - memoizedIsInitialized = 1; - return true; - } - - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - getSerializedSize(); - if (((bitField0_ & 0x00000001) == 0x00000001)) { - output.writeBytes(1, getContentTypeBytes()); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - output.writeUInt32(2, length_); - } - getUnknownFields().writeTo(output); - } - - private int memoizedSerializedSize = -1; - public int getSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (((bitField0_ & 0x00000001) == 0x00000001)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, getContentTypeBytes()); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - size += com.google.protobuf.CodedOutputStream - .computeUInt32Size(2, length_); - } - size += getUnknownFields().getSerializedSize(); - memoizedSerializedSize = size; - return size; - } - - private static final long serialVersionUID = 0L; - @java.lang.Override - protected java.lang.Object writeReplace() - throws java.io.ObjectStreamException { - return super.writeReplace(); - } - - public static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar parseFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - - public static Builder newBuilder() { return Builder.create(); } - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar prototype) { - return newBuilder().mergeFrom(prototype); - } - public Builder toBuilder() { return newBuilder(this); } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code signalservice.GroupDetails.Avatar} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessage.Builder - implements org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.AvatarOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_GroupDetails_Avatar_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_GroupDetails_Avatar_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar.class, org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar.Builder.class); - } - - // Construct using org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { - } - } - private static Builder create() { - return new Builder(); - } - - public Builder clear() { - super.clear(); - contentType_ = ""; - bitField0_ = (bitField0_ & ~0x00000001); - length_ = 0; - bitField0_ = (bitField0_ & ~0x00000002); - return this; - } - - public Builder clone() { - return create().mergeFrom(buildPartial()); - } - - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_GroupDetails_Avatar_descriptor; - } - - public org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar getDefaultInstanceForType() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar.getDefaultInstance(); - } - - public org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar build() { - org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - public org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar buildPartial() { - org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar result = new org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) == 0x00000001)) { - to_bitField0_ |= 0x00000001; - } - result.contentType_ = contentType_; - if (((from_bitField0_ & 0x00000002) == 0x00000002)) { - to_bitField0_ |= 0x00000002; - } - result.length_ = length_; - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar) { - return mergeFrom((org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar other) { - if (other == org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar.getDefaultInstance()) return this; - if (other.hasContentType()) { - bitField0_ |= 0x00000001; - contentType_ = other.contentType_; - onChanged(); - } - if (other.hasLength()) { - setLength(other.getLength()); - } - this.mergeUnknownFields(other.getUnknownFields()); - return this; - } - - public final boolean isInitialized() { - return true; - } - - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar) e.getUnfinishedMessage(); - throw e; - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - // optional string contentType = 1; - private java.lang.Object contentType_ = ""; - /** - * optional string contentType = 1; - */ - public boolean hasContentType() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional string contentType = 1; - */ - public java.lang.String getContentType() { - java.lang.Object ref = contentType_; - if (!(ref instanceof java.lang.String)) { - java.lang.String s = ((com.google.protobuf.ByteString) ref) - .toStringUtf8(); - contentType_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * optional string contentType = 1; - */ - public com.google.protobuf.ByteString - getContentTypeBytes() { - java.lang.Object ref = contentType_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - contentType_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * optional string contentType = 1; - */ - public Builder setContentType( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - contentType_ = value; - onChanged(); - return this; - } - /** - * optional string contentType = 1; - */ - public Builder clearContentType() { - bitField0_ = (bitField0_ & ~0x00000001); - contentType_ = getDefaultInstance().getContentType(); - onChanged(); - return this; - } - /** - * optional string contentType = 1; - */ - public Builder setContentTypeBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - contentType_ = value; - onChanged(); - return this; - } - - // optional uint32 length = 2; - private int length_ ; - /** - * optional uint32 length = 2; - */ - public boolean hasLength() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional uint32 length = 2; - */ - public int getLength() { - return length_; - } - /** - * optional uint32 length = 2; - */ - public Builder setLength(int value) { - bitField0_ |= 0x00000002; - length_ = value; - onChanged(); - return this; - } - /** - * optional uint32 length = 2; - */ - public Builder clearLength() { - bitField0_ = (bitField0_ & ~0x00000002); - length_ = 0; - onChanged(); - return this; - } - - // @@protoc_insertion_point(builder_scope:signalservice.GroupDetails.Avatar) - } - - static { - defaultInstance = new Avatar(true); - defaultInstance.initFields(); - } - - // @@protoc_insertion_point(class_scope:signalservice.GroupDetails.Avatar) - } - - private int bitField0_; - // optional bytes id = 1; - public static final int ID_FIELD_NUMBER = 1; - private com.google.protobuf.ByteString id_; - /** - * optional bytes id = 1; - * - *
-     * @required
-     * 
- */ - public boolean hasId() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional bytes id = 1; - * - *
-     * @required
-     * 
- */ - public com.google.protobuf.ByteString getId() { - return id_; - } - - // optional string name = 2; - public static final int NAME_FIELD_NUMBER = 2; - private java.lang.Object name_; - /** - * optional string name = 2; - */ - public boolean hasName() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional string name = 2; - */ - public java.lang.String getName() { - java.lang.Object ref = name_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - name_ = s; - } - return s; - } - } - /** - * optional string name = 2; - */ - public com.google.protobuf.ByteString - getNameBytes() { - java.lang.Object ref = name_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - name_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - // repeated string members = 3; - public static final int MEMBERS_FIELD_NUMBER = 3; - private com.google.protobuf.LazyStringList members_; - /** - * repeated string members = 3; - */ - public java.util.List - getMembersList() { - return members_; - } - /** - * repeated string members = 3; - */ - public int getMembersCount() { - return members_.size(); - } - /** - * repeated string members = 3; - */ - public java.lang.String getMembers(int index) { - return members_.get(index); - } - /** - * repeated string members = 3; - */ - public com.google.protobuf.ByteString - getMembersBytes(int index) { - return members_.getByteString(index); - } - - // optional .signalservice.GroupDetails.Avatar avatar = 4; - public static final int AVATAR_FIELD_NUMBER = 4; - private org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar avatar_; - /** - * optional .signalservice.GroupDetails.Avatar avatar = 4; - */ - public boolean hasAvatar() { - return ((bitField0_ & 0x00000004) == 0x00000004); - } - /** - * optional .signalservice.GroupDetails.Avatar avatar = 4; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar getAvatar() { - return avatar_; - } - /** - * optional .signalservice.GroupDetails.Avatar avatar = 4; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.AvatarOrBuilder getAvatarOrBuilder() { - return avatar_; - } - - // optional bool active = 5 [default = true]; - public static final int ACTIVE_FIELD_NUMBER = 5; - private boolean active_; - /** - * optional bool active = 5 [default = true]; - */ - public boolean hasActive() { - return ((bitField0_ & 0x00000008) == 0x00000008); - } - /** - * optional bool active = 5 [default = true]; - */ - public boolean getActive() { - return active_; - } - - // optional uint32 expireTimer = 6; - public static final int EXPIRETIMER_FIELD_NUMBER = 6; - private int expireTimer_; - /** - * optional uint32 expireTimer = 6; - */ - public boolean hasExpireTimer() { - return ((bitField0_ & 0x00000010) == 0x00000010); - } - /** - * optional uint32 expireTimer = 6; - */ - public int getExpireTimer() { - return expireTimer_; - } - - // optional string color = 7; - public static final int COLOR_FIELD_NUMBER = 7; - private java.lang.Object color_; - /** - * optional string color = 7; - */ - public boolean hasColor() { - return ((bitField0_ & 0x00000020) == 0x00000020); - } - /** - * optional string color = 7; - */ - public java.lang.String getColor() { - java.lang.Object ref = color_; - if (ref instanceof java.lang.String) { - return (java.lang.String) ref; - } else { - com.google.protobuf.ByteString bs = - (com.google.protobuf.ByteString) ref; - java.lang.String s = bs.toStringUtf8(); - if (bs.isValidUtf8()) { - color_ = s; - } - return s; - } - } - /** - * optional string color = 7; - */ - public com.google.protobuf.ByteString - getColorBytes() { - java.lang.Object ref = color_; - if (ref instanceof java.lang.String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - color_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - - // optional bool blocked = 8; - public static final int BLOCKED_FIELD_NUMBER = 8; - private boolean blocked_; - /** - * optional bool blocked = 8; - */ - public boolean hasBlocked() { - return ((bitField0_ & 0x00000040) == 0x00000040); - } - /** - * optional bool blocked = 8; - */ - public boolean getBlocked() { - return blocked_; - } - - // repeated string admins = 9; - public static final int ADMINS_FIELD_NUMBER = 9; - private com.google.protobuf.LazyStringList admins_; - /** - * repeated string admins = 9; - */ - public java.util.List - getAdminsList() { - return admins_; - } - /** - * repeated string admins = 9; - */ - public int getAdminsCount() { - return admins_.size(); - } - /** - * repeated string admins = 9; - */ - public java.lang.String getAdmins(int index) { - return admins_.get(index); - } - /** - * repeated string admins = 9; - */ - public com.google.protobuf.ByteString - getAdminsBytes(int index) { - return admins_.getByteString(index); - } - - private void initFields() { - id_ = com.google.protobuf.ByteString.EMPTY; - name_ = ""; - members_ = com.google.protobuf.LazyStringArrayList.EMPTY; - avatar_ = org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar.getDefaultInstance(); - active_ = true; - expireTimer_ = 0; - color_ = ""; - blocked_ = false; - admins_ = com.google.protobuf.LazyStringArrayList.EMPTY; - } - private byte memoizedIsInitialized = -1; - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized != -1) return isInitialized == 1; - - memoizedIsInitialized = 1; - return true; - } - - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - getSerializedSize(); - if (((bitField0_ & 0x00000001) == 0x00000001)) { - output.writeBytes(1, id_); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - output.writeBytes(2, getNameBytes()); - } - for (int i = 0; i < members_.size(); i++) { - output.writeBytes(3, members_.getByteString(i)); - } - if (((bitField0_ & 0x00000004) == 0x00000004)) { - output.writeMessage(4, avatar_); - } - if (((bitField0_ & 0x00000008) == 0x00000008)) { - output.writeBool(5, active_); - } - if (((bitField0_ & 0x00000010) == 0x00000010)) { - output.writeUInt32(6, expireTimer_); - } - if (((bitField0_ & 0x00000020) == 0x00000020)) { - output.writeBytes(7, getColorBytes()); - } - if (((bitField0_ & 0x00000040) == 0x00000040)) { - output.writeBool(8, blocked_); - } - for (int i = 0; i < admins_.size(); i++) { - output.writeBytes(9, admins_.getByteString(i)); - } - getUnknownFields().writeTo(output); - } - - private int memoizedSerializedSize = -1; - public int getSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (((bitField0_ & 0x00000001) == 0x00000001)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(1, id_); - } - if (((bitField0_ & 0x00000002) == 0x00000002)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(2, getNameBytes()); - } - { - int dataSize = 0; - for (int i = 0; i < members_.size(); i++) { - dataSize += com.google.protobuf.CodedOutputStream - .computeBytesSizeNoTag(members_.getByteString(i)); - } - size += dataSize; - size += 1 * getMembersList().size(); - } - if (((bitField0_ & 0x00000004) == 0x00000004)) { - size += com.google.protobuf.CodedOutputStream - .computeMessageSize(4, avatar_); - } - if (((bitField0_ & 0x00000008) == 0x00000008)) { - size += com.google.protobuf.CodedOutputStream - .computeBoolSize(5, active_); - } - if (((bitField0_ & 0x00000010) == 0x00000010)) { - size += com.google.protobuf.CodedOutputStream - .computeUInt32Size(6, expireTimer_); - } - if (((bitField0_ & 0x00000020) == 0x00000020)) { - size += com.google.protobuf.CodedOutputStream - .computeBytesSize(7, getColorBytes()); - } - if (((bitField0_ & 0x00000040) == 0x00000040)) { - size += com.google.protobuf.CodedOutputStream - .computeBoolSize(8, blocked_); - } - { - int dataSize = 0; - for (int i = 0; i < admins_.size(); i++) { - dataSize += com.google.protobuf.CodedOutputStream - .computeBytesSizeNoTag(admins_.getByteString(i)); - } - size += dataSize; - size += 1 * getAdminsList().size(); - } - size += getUnknownFields().getSerializedSize(); - memoizedSerializedSize = size; - return size; - } - - private static final long serialVersionUID = 0L; - @java.lang.Override - protected java.lang.Object writeReplace() - throws java.io.ObjectStreamException { - return super.writeReplace(); - } - - public static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails parseFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - - public static Builder newBuilder() { return Builder.create(); } - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails prototype) { - return newBuilder().mergeFrom(prototype); - } - public Builder toBuilder() { return newBuilder(this); } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code signalservice.GroupDetails} - */ - public static final class Builder extends - com.google.protobuf.GeneratedMessage.Builder - implements org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetailsOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_GroupDetails_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_GroupDetails_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.class, org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Builder.class); - } - - // Construct using org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { - getAvatarFieldBuilder(); - } - } - private static Builder create() { - return new Builder(); - } - - public Builder clear() { - super.clear(); - id_ = com.google.protobuf.ByteString.EMPTY; - bitField0_ = (bitField0_ & ~0x00000001); - name_ = ""; - bitField0_ = (bitField0_ & ~0x00000002); - members_ = com.google.protobuf.LazyStringArrayList.EMPTY; - bitField0_ = (bitField0_ & ~0x00000004); - if (avatarBuilder_ == null) { - avatar_ = org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar.getDefaultInstance(); - } else { - avatarBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000008); - active_ = true; - bitField0_ = (bitField0_ & ~0x00000010); - expireTimer_ = 0; - bitField0_ = (bitField0_ & ~0x00000020); - color_ = ""; - bitField0_ = (bitField0_ & ~0x00000040); - blocked_ = false; - bitField0_ = (bitField0_ & ~0x00000080); - admins_ = com.google.protobuf.LazyStringArrayList.EMPTY; - bitField0_ = (bitField0_ & ~0x00000100); - return this; - } - - public Builder clone() { - return create().mergeFrom(buildPartial()); - } - - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_GroupDetails_descriptor; - } - - public org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails getDefaultInstanceForType() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.getDefaultInstance(); - } - - public org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails build() { - org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - public org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails buildPartial() { - org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails result = new org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) == 0x00000001)) { - to_bitField0_ |= 0x00000001; - } - result.id_ = id_; - if (((from_bitField0_ & 0x00000002) == 0x00000002)) { - to_bitField0_ |= 0x00000002; - } - result.name_ = name_; - if (((bitField0_ & 0x00000004) == 0x00000004)) { - members_ = new com.google.protobuf.UnmodifiableLazyStringList( - members_); - bitField0_ = (bitField0_ & ~0x00000004); - } - result.members_ = members_; - if (((from_bitField0_ & 0x00000008) == 0x00000008)) { - to_bitField0_ |= 0x00000004; - } - if (avatarBuilder_ == null) { - result.avatar_ = avatar_; - } else { - result.avatar_ = avatarBuilder_.build(); - } - if (((from_bitField0_ & 0x00000010) == 0x00000010)) { - to_bitField0_ |= 0x00000008; - } - result.active_ = active_; - if (((from_bitField0_ & 0x00000020) == 0x00000020)) { - to_bitField0_ |= 0x00000010; - } - result.expireTimer_ = expireTimer_; - if (((from_bitField0_ & 0x00000040) == 0x00000040)) { - to_bitField0_ |= 0x00000020; - } - result.color_ = color_; - if (((from_bitField0_ & 0x00000080) == 0x00000080)) { - to_bitField0_ |= 0x00000040; - } - result.blocked_ = blocked_; - if (((bitField0_ & 0x00000100) == 0x00000100)) { - admins_ = new com.google.protobuf.UnmodifiableLazyStringList( - admins_); - bitField0_ = (bitField0_ & ~0x00000100); - } - result.admins_ = admins_; - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails) { - return mergeFrom((org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails other) { - if (other == org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.getDefaultInstance()) return this; - if (other.hasId()) { - setId(other.getId()); - } - if (other.hasName()) { - bitField0_ |= 0x00000002; - name_ = other.name_; - onChanged(); - } - if (!other.members_.isEmpty()) { - if (members_.isEmpty()) { - members_ = other.members_; - bitField0_ = (bitField0_ & ~0x00000004); - } else { - ensureMembersIsMutable(); - members_.addAll(other.members_); - } - onChanged(); - } - if (other.hasAvatar()) { - mergeAvatar(other.getAvatar()); - } - if (other.hasActive()) { - setActive(other.getActive()); - } - if (other.hasExpireTimer()) { - setExpireTimer(other.getExpireTimer()); - } - if (other.hasColor()) { - bitField0_ |= 0x00000040; - color_ = other.color_; - onChanged(); - } - if (other.hasBlocked()) { - setBlocked(other.getBlocked()); - } - if (!other.admins_.isEmpty()) { - if (admins_.isEmpty()) { - admins_ = other.admins_; - bitField0_ = (bitField0_ & ~0x00000100); - } else { - ensureAdminsIsMutable(); - admins_.addAll(other.admins_); - } - onChanged(); - } - this.mergeUnknownFields(other.getUnknownFields()); - return this; - } - - public final boolean isInitialized() { - return true; - } - - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails) e.getUnfinishedMessage(); - throw e; - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - // optional bytes id = 1; - private com.google.protobuf.ByteString id_ = com.google.protobuf.ByteString.EMPTY; - /** - * optional bytes id = 1; - * - *
-       * @required
-       * 
- */ - public boolean hasId() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional bytes id = 1; - * - *
-       * @required
-       * 
- */ - public com.google.protobuf.ByteString getId() { - return id_; - } - /** - * optional bytes id = 1; - * - *
-       * @required
-       * 
- */ - public Builder setId(com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000001; - id_ = value; - onChanged(); - return this; - } - /** - * optional bytes id = 1; - * - *
-       * @required
-       * 
- */ - public Builder clearId() { - bitField0_ = (bitField0_ & ~0x00000001); - id_ = getDefaultInstance().getId(); - onChanged(); - return this; - } - - // optional string name = 2; - private java.lang.Object name_ = ""; - /** - * optional string name = 2; - */ - public boolean hasName() { - return ((bitField0_ & 0x00000002) == 0x00000002); - } - /** - * optional string name = 2; - */ - public java.lang.String getName() { - java.lang.Object ref = name_; - if (!(ref instanceof java.lang.String)) { - java.lang.String s = ((com.google.protobuf.ByteString) ref) - .toStringUtf8(); - name_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * optional string name = 2; - */ - public com.google.protobuf.ByteString - getNameBytes() { - java.lang.Object ref = name_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - name_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * optional string name = 2; - */ - public Builder setName( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000002; - name_ = value; - onChanged(); - return this; - } - /** - * optional string name = 2; - */ - public Builder clearName() { - bitField0_ = (bitField0_ & ~0x00000002); - name_ = getDefaultInstance().getName(); - onChanged(); - return this; - } - /** - * optional string name = 2; - */ - public Builder setNameBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000002; - name_ = value; - onChanged(); - return this; - } - - // repeated string members = 3; - private com.google.protobuf.LazyStringList members_ = com.google.protobuf.LazyStringArrayList.EMPTY; - private void ensureMembersIsMutable() { - if (!((bitField0_ & 0x00000004) == 0x00000004)) { - members_ = new com.google.protobuf.LazyStringArrayList(members_); - bitField0_ |= 0x00000004; - } - } - /** - * repeated string members = 3; - */ - public java.util.List - getMembersList() { - return java.util.Collections.unmodifiableList(members_); - } - /** - * repeated string members = 3; - */ - public int getMembersCount() { - return members_.size(); - } - /** - * repeated string members = 3; - */ - public java.lang.String getMembers(int index) { - return members_.get(index); - } - /** - * repeated string members = 3; - */ - public com.google.protobuf.ByteString - getMembersBytes(int index) { - return members_.getByteString(index); - } - /** - * repeated string members = 3; - */ - public Builder setMembers( - int index, java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - ensureMembersIsMutable(); - members_.set(index, value); - onChanged(); - return this; - } - /** - * repeated string members = 3; - */ - public Builder addMembers( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - ensureMembersIsMutable(); - members_.add(value); - onChanged(); - return this; - } - /** - * repeated string members = 3; - */ - public Builder addAllMembers( - java.lang.Iterable values) { - ensureMembersIsMutable(); - super.addAll(values, members_); - onChanged(); - return this; - } - /** - * repeated string members = 3; - */ - public Builder clearMembers() { - members_ = com.google.protobuf.LazyStringArrayList.EMPTY; - bitField0_ = (bitField0_ & ~0x00000004); - onChanged(); - return this; - } - /** - * repeated string members = 3; - */ - public Builder addMembersBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - ensureMembersIsMutable(); - members_.add(value); - onChanged(); - return this; - } - - // optional .signalservice.GroupDetails.Avatar avatar = 4; - private org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar avatar_ = org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar.getDefaultInstance(); - private com.google.protobuf.SingleFieldBuilder< - org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar, org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.AvatarOrBuilder> avatarBuilder_; - /** - * optional .signalservice.GroupDetails.Avatar avatar = 4; - */ - public boolean hasAvatar() { - return ((bitField0_ & 0x00000008) == 0x00000008); - } - /** - * optional .signalservice.GroupDetails.Avatar avatar = 4; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar getAvatar() { - if (avatarBuilder_ == null) { - return avatar_; - } else { - return avatarBuilder_.getMessage(); - } - } - /** - * optional .signalservice.GroupDetails.Avatar avatar = 4; - */ - public Builder setAvatar(org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar value) { - if (avatarBuilder_ == null) { - if (value == null) { - throw new NullPointerException(); - } - avatar_ = value; - onChanged(); - } else { - avatarBuilder_.setMessage(value); - } - bitField0_ |= 0x00000008; - return this; - } - /** - * optional .signalservice.GroupDetails.Avatar avatar = 4; - */ - public Builder setAvatar( - org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar.Builder builderForValue) { - if (avatarBuilder_ == null) { - avatar_ = builderForValue.build(); - onChanged(); - } else { - avatarBuilder_.setMessage(builderForValue.build()); - } - bitField0_ |= 0x00000008; - return this; - } - /** - * optional .signalservice.GroupDetails.Avatar avatar = 4; - */ - public Builder mergeAvatar(org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar value) { - if (avatarBuilder_ == null) { - if (((bitField0_ & 0x00000008) == 0x00000008) && - avatar_ != org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar.getDefaultInstance()) { - avatar_ = - org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar.newBuilder(avatar_).mergeFrom(value).buildPartial(); - } else { - avatar_ = value; - } - onChanged(); - } else { - avatarBuilder_.mergeFrom(value); - } - bitField0_ |= 0x00000008; - return this; - } - /** - * optional .signalservice.GroupDetails.Avatar avatar = 4; - */ - public Builder clearAvatar() { - if (avatarBuilder_ == null) { - avatar_ = org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar.getDefaultInstance(); - onChanged(); - } else { - avatarBuilder_.clear(); - } - bitField0_ = (bitField0_ & ~0x00000008); - return this; - } - /** - * optional .signalservice.GroupDetails.Avatar avatar = 4; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar.Builder getAvatarBuilder() { - bitField0_ |= 0x00000008; - onChanged(); - return getAvatarFieldBuilder().getBuilder(); - } - /** - * optional .signalservice.GroupDetails.Avatar avatar = 4; - */ - public org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.AvatarOrBuilder getAvatarOrBuilder() { - if (avatarBuilder_ != null) { - return avatarBuilder_.getMessageOrBuilder(); - } else { - return avatar_; - } - } - /** - * optional .signalservice.GroupDetails.Avatar avatar = 4; - */ - private com.google.protobuf.SingleFieldBuilder< - org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar, org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.AvatarOrBuilder> - getAvatarFieldBuilder() { - if (avatarBuilder_ == null) { - avatarBuilder_ = new com.google.protobuf.SingleFieldBuilder< - org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar, org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.Avatar.Builder, org.session.libsignal.service.internal.push.SignalServiceProtos.GroupDetails.AvatarOrBuilder>( - avatar_, - getParentForChildren(), - isClean()); - avatar_ = null; - } - return avatarBuilder_; - } - - // optional bool active = 5 [default = true]; - private boolean active_ = true; - /** - * optional bool active = 5 [default = true]; - */ - public boolean hasActive() { - return ((bitField0_ & 0x00000010) == 0x00000010); - } - /** - * optional bool active = 5 [default = true]; - */ - public boolean getActive() { - return active_; - } - /** - * optional bool active = 5 [default = true]; - */ - public Builder setActive(boolean value) { - bitField0_ |= 0x00000010; - active_ = value; - onChanged(); - return this; - } - /** - * optional bool active = 5 [default = true]; - */ - public Builder clearActive() { - bitField0_ = (bitField0_ & ~0x00000010); - active_ = true; - onChanged(); - return this; - } - - // optional uint32 expireTimer = 6; - private int expireTimer_ ; - /** - * optional uint32 expireTimer = 6; - */ - public boolean hasExpireTimer() { - return ((bitField0_ & 0x00000020) == 0x00000020); - } - /** - * optional uint32 expireTimer = 6; - */ - public int getExpireTimer() { - return expireTimer_; - } - /** - * optional uint32 expireTimer = 6; - */ - public Builder setExpireTimer(int value) { - bitField0_ |= 0x00000020; - expireTimer_ = value; - onChanged(); - return this; - } - /** - * optional uint32 expireTimer = 6; - */ - public Builder clearExpireTimer() { - bitField0_ = (bitField0_ & ~0x00000020); - expireTimer_ = 0; - onChanged(); - return this; - } - - // optional string color = 7; - private java.lang.Object color_ = ""; - /** - * optional string color = 7; - */ - public boolean hasColor() { - return ((bitField0_ & 0x00000040) == 0x00000040); - } - /** - * optional string color = 7; - */ - public java.lang.String getColor() { - java.lang.Object ref = color_; - if (!(ref instanceof java.lang.String)) { - java.lang.String s = ((com.google.protobuf.ByteString) ref) - .toStringUtf8(); - color_ = s; - return s; - } else { - return (java.lang.String) ref; - } - } - /** - * optional string color = 7; - */ - public com.google.protobuf.ByteString - getColorBytes() { - java.lang.Object ref = color_; - if (ref instanceof String) { - com.google.protobuf.ByteString b = - com.google.protobuf.ByteString.copyFromUtf8( - (java.lang.String) ref); - color_ = b; - return b; - } else { - return (com.google.protobuf.ByteString) ref; - } - } - /** - * optional string color = 7; - */ - public Builder setColor( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000040; - color_ = value; - onChanged(); - return this; - } - /** - * optional string color = 7; - */ - public Builder clearColor() { - bitField0_ = (bitField0_ & ~0x00000040); - color_ = getDefaultInstance().getColor(); - onChanged(); - return this; - } - /** - * optional string color = 7; - */ - public Builder setColorBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - bitField0_ |= 0x00000040; - color_ = value; - onChanged(); - return this; - } - - // optional bool blocked = 8; - private boolean blocked_ ; - /** - * optional bool blocked = 8; - */ - public boolean hasBlocked() { - return ((bitField0_ & 0x00000080) == 0x00000080); - } - /** - * optional bool blocked = 8; - */ - public boolean getBlocked() { - return blocked_; - } - /** - * optional bool blocked = 8; - */ - public Builder setBlocked(boolean value) { - bitField0_ |= 0x00000080; - blocked_ = value; - onChanged(); - return this; - } - /** - * optional bool blocked = 8; - */ - public Builder clearBlocked() { - bitField0_ = (bitField0_ & ~0x00000080); - blocked_ = false; - onChanged(); - return this; - } - - // repeated string admins = 9; - private com.google.protobuf.LazyStringList admins_ = com.google.protobuf.LazyStringArrayList.EMPTY; - private void ensureAdminsIsMutable() { - if (!((bitField0_ & 0x00000100) == 0x00000100)) { - admins_ = new com.google.protobuf.LazyStringArrayList(admins_); - bitField0_ |= 0x00000100; - } - } - /** - * repeated string admins = 9; - */ - public java.util.List - getAdminsList() { - return java.util.Collections.unmodifiableList(admins_); - } - /** - * repeated string admins = 9; - */ - public int getAdminsCount() { - return admins_.size(); - } - /** - * repeated string admins = 9; - */ - public java.lang.String getAdmins(int index) { - return admins_.get(index); - } - /** - * repeated string admins = 9; - */ - public com.google.protobuf.ByteString - getAdminsBytes(int index) { - return admins_.getByteString(index); - } - /** - * repeated string admins = 9; - */ - public Builder setAdmins( - int index, java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - ensureAdminsIsMutable(); - admins_.set(index, value); - onChanged(); - return this; - } - /** - * repeated string admins = 9; - */ - public Builder addAdmins( - java.lang.String value) { - if (value == null) { - throw new NullPointerException(); - } - ensureAdminsIsMutable(); - admins_.add(value); - onChanged(); - return this; - } - /** - * repeated string admins = 9; - */ - public Builder addAllAdmins( - java.lang.Iterable values) { - ensureAdminsIsMutable(); - super.addAll(values, admins_); - onChanged(); - return this; - } - /** - * repeated string admins = 9; - */ - public Builder clearAdmins() { - admins_ = com.google.protobuf.LazyStringArrayList.EMPTY; - bitField0_ = (bitField0_ & ~0x00000100); - onChanged(); - return this; - } - /** - * repeated string admins = 9; - */ - public Builder addAdminsBytes( - com.google.protobuf.ByteString value) { - if (value == null) { - throw new NullPointerException(); - } - ensureAdminsIsMutable(); - admins_.add(value); - onChanged(); - return this; - } - - // @@protoc_insertion_point(builder_scope:signalservice.GroupDetails) - } - - static { - defaultInstance = new GroupDetails(true); - defaultInstance.initFields(); - } - - // @@protoc_insertion_point(class_scope:signalservice.GroupDetails) - } - - public interface PublicChatInfoOrBuilder - extends com.google.protobuf.MessageOrBuilder { - - // optional uint64 serverID = 1; - /** - * optional uint64 serverID = 1; - */ - boolean hasServerID(); - /** - * optional uint64 serverID = 1; - */ - long getServerID(); - } - /** - * Protobuf type {@code signalservice.PublicChatInfo} - * - *
-   * Intended for internal use only
-   * 
- */ - public static final class PublicChatInfo extends - com.google.protobuf.GeneratedMessage - implements PublicChatInfoOrBuilder { - // Use PublicChatInfo.newBuilder() to construct. - private PublicChatInfo(com.google.protobuf.GeneratedMessage.Builder builder) { - super(builder); - this.unknownFields = builder.getUnknownFields(); - } - private PublicChatInfo(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } - - private static final PublicChatInfo defaultInstance; - public static PublicChatInfo getDefaultInstance() { - return defaultInstance; - } - - public PublicChatInfo getDefaultInstanceForType() { - return defaultInstance; - } - - private final com.google.protobuf.UnknownFieldSet unknownFields; - @java.lang.Override - public final com.google.protobuf.UnknownFieldSet - getUnknownFields() { - return this.unknownFields; - } - private PublicChatInfo( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - initFields(); - int mutable_bitField0_ = 0; - com.google.protobuf.UnknownFieldSet.Builder unknownFields = - com.google.protobuf.UnknownFieldSet.newBuilder(); - try { - boolean done = false; - while (!done) { - int tag = input.readTag(); - switch (tag) { - case 0: - done = true; - break; - default: { - if (!parseUnknownField(input, unknownFields, - extensionRegistry, tag)) { - done = true; - } - break; - } - case 8: { - bitField0_ |= 0x00000001; - serverID_ = input.readUInt64(); - break; - } - } - } - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - throw e.setUnfinishedMessage(this); - } catch (java.io.IOException e) { - throw new com.google.protobuf.InvalidProtocolBufferException( - e.getMessage()).setUnfinishedMessage(this); - } finally { - this.unknownFields = unknownFields.build(); - makeExtensionsImmutable(); - } - } - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_PublicChatInfo_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_PublicChatInfo_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo.class, org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo.Builder.class); - } - - public static com.google.protobuf.Parser PARSER = - new com.google.protobuf.AbstractParser() { - public PublicChatInfo parsePartialFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return new PublicChatInfo(input, extensionRegistry); - } - }; - - @java.lang.Override - public com.google.protobuf.Parser getParserForType() { - return PARSER; - } - - private int bitField0_; - // optional uint64 serverID = 1; - public static final int SERVERID_FIELD_NUMBER = 1; - private long serverID_; - /** - * optional uint64 serverID = 1; - */ - public boolean hasServerID() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional uint64 serverID = 1; - */ - public long getServerID() { - return serverID_; - } - - private void initFields() { - serverID_ = 0L; - } - private byte memoizedIsInitialized = -1; - public final boolean isInitialized() { - byte isInitialized = memoizedIsInitialized; - if (isInitialized != -1) return isInitialized == 1; - - memoizedIsInitialized = 1; - return true; - } - - public void writeTo(com.google.protobuf.CodedOutputStream output) - throws java.io.IOException { - getSerializedSize(); - if (((bitField0_ & 0x00000001) == 0x00000001)) { - output.writeUInt64(1, serverID_); - } - getUnknownFields().writeTo(output); - } - - private int memoizedSerializedSize = -1; - public int getSerializedSize() { - int size = memoizedSerializedSize; - if (size != -1) return size; - - size = 0; - if (((bitField0_ & 0x00000001) == 0x00000001)) { - size += com.google.protobuf.CodedOutputStream - .computeUInt64Size(1, serverID_); - } - size += getUnknownFields().getSerializedSize(); - memoizedSerializedSize = size; - return size; - } - - private static final long serialVersionUID = 0L; - @java.lang.Override - protected java.lang.Object writeReplace() - throws java.io.ObjectStreamException { - return super.writeReplace(); - } - - public static org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo parseFrom( - com.google.protobuf.ByteString data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo parseFrom( - com.google.protobuf.ByteString data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo parseFrom(byte[] data) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo parseFrom( - byte[] data, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws com.google.protobuf.InvalidProtocolBufferException { - return PARSER.parseFrom(data, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo parseFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo parseFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo parseDelimitedFrom(java.io.InputStream input) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo parseDelimitedFrom( - java.io.InputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseDelimitedFrom(input, extensionRegistry); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo parseFrom( - com.google.protobuf.CodedInputStream input) - throws java.io.IOException { - return PARSER.parseFrom(input); - } - public static org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo parseFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - return PARSER.parseFrom(input, extensionRegistry); - } - - public static Builder newBuilder() { return Builder.create(); } - public Builder newBuilderForType() { return newBuilder(); } - public static Builder newBuilder(org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo prototype) { - return newBuilder().mergeFrom(prototype); - } - public Builder toBuilder() { return newBuilder(this); } - - @java.lang.Override - protected Builder newBuilderForType( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - Builder builder = new Builder(parent); - return builder; - } - /** - * Protobuf type {@code signalservice.PublicChatInfo} - * - *
-     * Intended for internal use only
-     * 
- */ - public static final class Builder extends - com.google.protobuf.GeneratedMessage.Builder - implements org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfoOrBuilder { - public static final com.google.protobuf.Descriptors.Descriptor - getDescriptor() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_PublicChatInfo_descriptor; - } - - protected com.google.protobuf.GeneratedMessage.FieldAccessorTable - internalGetFieldAccessorTable() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_PublicChatInfo_fieldAccessorTable - .ensureFieldAccessorsInitialized( - org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo.class, org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo.Builder.class); - } - - // Construct using org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo.newBuilder() - private Builder() { - maybeForceBuilderInitialization(); - } - - private Builder( - com.google.protobuf.GeneratedMessage.BuilderParent parent) { - super(parent); - maybeForceBuilderInitialization(); - } - private void maybeForceBuilderInitialization() { - if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { - } - } - private static Builder create() { - return new Builder(); - } - - public Builder clear() { - super.clear(); - serverID_ = 0L; - bitField0_ = (bitField0_ & ~0x00000001); - return this; - } - - public Builder clone() { - return create().mergeFrom(buildPartial()); - } - - public com.google.protobuf.Descriptors.Descriptor - getDescriptorForType() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.internal_static_signalservice_PublicChatInfo_descriptor; - } - - public org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo getDefaultInstanceForType() { - return org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo.getDefaultInstance(); - } - - public org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo build() { - org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo result = buildPartial(); - if (!result.isInitialized()) { - throw newUninitializedMessageException(result); - } - return result; - } - - public org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo buildPartial() { - org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo result = new org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo(this); - int from_bitField0_ = bitField0_; - int to_bitField0_ = 0; - if (((from_bitField0_ & 0x00000001) == 0x00000001)) { - to_bitField0_ |= 0x00000001; - } - result.serverID_ = serverID_; - result.bitField0_ = to_bitField0_; - onBuilt(); - return result; - } - - public Builder mergeFrom(com.google.protobuf.Message other) { - if (other instanceof org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo) { - return mergeFrom((org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo)other); - } else { - super.mergeFrom(other); - return this; - } - } - - public Builder mergeFrom(org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo other) { - if (other == org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo.getDefaultInstance()) return this; - if (other.hasServerID()) { - setServerID(other.getServerID()); - } - this.mergeUnknownFields(other.getUnknownFields()); - return this; - } - - public final boolean isInitialized() { - return true; - } - - public Builder mergeFrom( - com.google.protobuf.CodedInputStream input, - com.google.protobuf.ExtensionRegistryLite extensionRegistry) - throws java.io.IOException { - org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo parsedMessage = null; - try { - parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); - } catch (com.google.protobuf.InvalidProtocolBufferException e) { - parsedMessage = (org.session.libsignal.service.internal.push.SignalServiceProtos.PublicChatInfo) e.getUnfinishedMessage(); - throw e; - } finally { - if (parsedMessage != null) { - mergeFrom(parsedMessage); - } - } - return this; - } - private int bitField0_; - - // optional uint64 serverID = 1; - private long serverID_ ; - /** - * optional uint64 serverID = 1; - */ - public boolean hasServerID() { - return ((bitField0_ & 0x00000001) == 0x00000001); - } - /** - * optional uint64 serverID = 1; - */ - public long getServerID() { - return serverID_; - } - /** - * optional uint64 serverID = 1; - */ - public Builder setServerID(long value) { - bitField0_ |= 0x00000001; - serverID_ = value; - onChanged(); - return this; - } - /** - * optional uint64 serverID = 1; - */ - public Builder clearServerID() { - bitField0_ = (bitField0_ & ~0x00000001); - serverID_ = 0L; - onChanged(); - return this; - } - - // @@protoc_insertion_point(builder_scope:signalservice.PublicChatInfo) - } - - static { - defaultInstance = new PublicChatInfo(true); - defaultInstance.initFields(); - } - - // @@protoc_insertion_point(class_scope:signalservice.PublicChatInfo) - } - private static com.google.protobuf.Descriptors.Descriptor internal_static_signalservice_Envelope_descriptor; private static @@ -33208,11 +20154,6 @@ public final class SignalServiceProtos { private static com.google.protobuf.GeneratedMessage.FieldAccessorTable internal_static_signalservice_Content_fieldAccessorTable; - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signalservice_ClosedGroupCiphertextMessageWrapper_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signalservice_ClosedGroupCiphertextMessageWrapper_fieldAccessorTable; private static com.google.protobuf.Descriptors.Descriptor internal_static_signalservice_KeyPair_descriptor; private static @@ -33238,36 +20179,6 @@ public final class SignalServiceProtos { private static com.google.protobuf.GeneratedMessage.FieldAccessorTable internal_static_signalservice_DataMessage_Quote_QuotedAttachment_fieldAccessorTable; - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signalservice_DataMessage_Contact_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signalservice_DataMessage_Contact_fieldAccessorTable; - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signalservice_DataMessage_Contact_Name_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signalservice_DataMessage_Contact_Name_fieldAccessorTable; - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signalservice_DataMessage_Contact_Phone_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signalservice_DataMessage_Contact_Phone_fieldAccessorTable; - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signalservice_DataMessage_Contact_Email_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signalservice_DataMessage_Contact_Email_fieldAccessorTable; - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signalservice_DataMessage_Contact_PostalAddress_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signalservice_DataMessage_Contact_PostalAddress_fieldAccessorTable; - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signalservice_DataMessage_Contact_Avatar_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signalservice_DataMessage_Contact_Avatar_fieldAccessorTable; private static com.google.protobuf.Descriptors.Descriptor internal_static_signalservice_DataMessage_Preview_descriptor; private static @@ -33318,31 +20229,6 @@ public final class SignalServiceProtos { private static com.google.protobuf.GeneratedMessage.FieldAccessorTable internal_static_signalservice_GroupContext_fieldAccessorTable; - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signalservice_ContactDetails_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signalservice_ContactDetails_fieldAccessorTable; - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signalservice_ContactDetails_Avatar_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signalservice_ContactDetails_Avatar_fieldAccessorTable; - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signalservice_GroupDetails_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signalservice_GroupDetails_fieldAccessorTable; - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signalservice_GroupDetails_Avatar_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signalservice_GroupDetails_Avatar_fieldAccessorTable; - private static com.google.protobuf.Descriptors.Descriptor - internal_static_signalservice_PublicChatInfo_descriptor; - private static - com.google.protobuf.GeneratedMessage.FieldAccessorTable - internal_static_signalservice_PublicChatInfo_fieldAccessorTable; public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { @@ -33352,141 +20238,93 @@ public final class SignalServiceProtos { descriptor; static { java.lang.String[] descriptorData = { - "\n\023SignalService.proto\022\rsignalservice\"\327\001\n" + + "\n\023SignalService.proto\022\rsignalservice\"\320\001\n" + "\010Envelope\022*\n\004type\030\001 \002(\0162\034.signalservice." + "Envelope.Type\022\016\n\006source\030\002 \001(\t\022\024\n\014sourceD" + - "evice\030\007 \001(\r\022\021\n\ttimestamp\030\005 \001(\004\022\017\n\007conten" + - "t\030\010 \001(\014\022\027\n\017serverTimestamp\030\n \001(\004\"<\n\004Type" + - "\022\027\n\023UNIDENTIFIED_SENDER\020\006\022\033\n\027CLOSED_GROU" + - "P_CIPHERTEXT\020\007\"{\n\rTypingMessage\022\021\n\ttimes" + - "tamp\030\001 \001(\004\0223\n\006action\030\002 \001(\0162#.signalservi" + - "ce.TypingMessage.Action\"\"\n\006Action\022\013\n\007STA" + - "RTED\020\000\022\013\n\007STOPPED\020\001\"\270\002\n\007Content\022/\n\013dataM", - "essage\030\001 \001(\0132\032.signalservice.DataMessage" + - "\0225\n\016receiptMessage\030\005 \001(\0132\035.signalservice" + - ".ReceiptMessage\0223\n\rtypingMessage\030\006 \001(\0132\034" + - ".signalservice.TypingMessage\022A\n\024configur" + - "ationMessage\030\007 \001(\0132#.signalservice.Confi" + - "gurationMessage\022M\n\032dataExtractionNotific" + - "ation\030R \001(\0132).signalservice.DataExtracti" + - "onNotification\"U\n#ClosedGroupCiphertextM" + - "essageWrapper\022\022\n\nciphertext\030\001 \001(\014\022\032\n\022eph" + - "emeralPublicKey\030\002 \001(\014\"0\n\007KeyPair\022\021\n\tpubl", - "icKey\030\001 \002(\014\022\022\n\nprivateKey\030\002 \002(\014\"\226\001\n\032Data" + - "ExtractionNotification\022<\n\004type\030\001 \002(\0162..s" + - "ignalservice.DataExtractionNotification." + - "Type\022\021\n\ttimestamp\030\002 \001(\004\"\'\n\004Type\022\016\n\nSCREE" + - "NSHOT\020\001\022\017\n\013MEDIA_SAVED\020\002\"\357\024\n\013DataMessage" + - "\022\014\n\004body\030\001 \001(\t\0225\n\013attachments\030\002 \003(\0132 .si" + - "gnalservice.AttachmentPointer\022*\n\005group\030\003" + - " \001(\0132\033.signalservice.GroupContext\022\r\n\005fla" + - "gs\030\004 \001(\r\022\023\n\013expireTimer\030\005 \001(\r\022\022\n\nprofile" + - "Key\030\006 \001(\014\022\021\n\ttimestamp\030\007 \001(\004\022/\n\005quote\030\010 ", - "\001(\0132 .signalservice.DataMessage.Quote\0223\n" + - "\007contact\030\t \003(\0132\".signalservice.DataMessa" + - "ge.Contact\0223\n\007preview\030\n \003(\0132\".signalserv" + - "ice.DataMessage.Preview\0227\n\007profile\030e \001(\013" + - "2&.signalservice.DataMessage.LokiProfile" + - "\022W\n\031closedGroupControlMessage\030h \001(\01324.si" + - "gnalservice.DataMessage.ClosedGroupContr" + - "olMessage\022\022\n\nsyncTarget\030i \001(\t\0226\n\016publicC" + - "hatInfo\030\347\007 \001(\0132\035.signalservice.PublicCha" + - "tInfo\032\225\002\n\005Quote\022\n\n\002id\030\001 \001(\004\022\016\n\006author\030\002 ", - "\001(\t\022\014\n\004text\030\003 \001(\t\022F\n\013attachments\030\004 \003(\01321" + - ".signalservice.DataMessage.Quote.QuotedA" + - "ttachment\032\231\001\n\020QuotedAttachment\022\023\n\013conten" + - "tType\030\001 \001(\t\022\020\n\010fileName\030\002 \001(\t\0223\n\tthumbna" + - "il\030\003 \001(\0132 .signalservice.AttachmentPoint" + - "er\022\r\n\005flags\030\004 \001(\r\"\032\n\005Flags\022\021\n\rVOICE_MESS" + - "AGE\020\001\032\304\010\n\007Contact\0225\n\004name\030\001 \001(\0132\'.signal" + - "service.DataMessage.Contact.Name\0228\n\006numb" + - "er\030\003 \003(\0132(.signalservice.DataMessage.Con" + - "tact.Phone\0227\n\005email\030\004 \003(\0132(.signalservic", - "e.DataMessage.Contact.Email\022A\n\007address\030\005" + - " \003(\01320.signalservice.DataMessage.Contact" + - ".PostalAddress\0229\n\006avatar\030\006 \001(\0132).signals" + - "ervice.DataMessage.Contact.Avatar\022\024\n\014org" + - "anization\030\007 \001(\t\032v\n\004Name\022\021\n\tgivenName\030\001 \001" + - "(\t\022\022\n\nfamilyName\030\002 \001(\t\022\016\n\006prefix\030\003 \001(\t\022\016" + - "\n\006suffix\030\004 \001(\t\022\022\n\nmiddleName\030\005 \001(\t\022\023\n\013di" + - "splayName\030\006 \001(\t\032\226\001\n\005Phone\022\r\n\005value\030\001 \001(\t" + - "\022;\n\004type\030\002 \001(\0162-.signalservice.DataMessa" + - "ge.Contact.Phone.Type\022\r\n\005label\030\003 \001(\t\"2\n\004", - "Type\022\010\n\004HOME\020\001\022\n\n\006MOBILE\020\002\022\010\n\004WORK\020\003\022\n\n\006" + - "CUSTOM\020\004\032\226\001\n\005Email\022\r\n\005value\030\001 \001(\t\022;\n\004typ" + - "e\030\002 \001(\0162-.signalservice.DataMessage.Cont" + - "act.Email.Type\022\r\n\005label\030\003 \001(\t\"2\n\004Type\022\010\n" + - "\004HOME\020\001\022\n\n\006MOBILE\020\002\022\010\n\004WORK\020\003\022\n\n\006CUSTOM\020" + - "\004\032\201\002\n\rPostalAddress\022C\n\004type\030\001 \001(\01625.sign" + - "alservice.DataMessage.Contact.PostalAddr" + - "ess.Type\022\r\n\005label\030\002 \001(\t\022\016\n\006street\030\003 \001(\t\022" + - "\r\n\005pobox\030\004 \001(\t\022\024\n\014neighborhood\030\005 \001(\t\022\014\n\004" + - "city\030\006 \001(\t\022\016\n\006region\030\007 \001(\t\022\020\n\010postcode\030\010", - " \001(\t\022\017\n\007country\030\t \001(\t\"&\n\004Type\022\010\n\004HOME\020\001\022" + - "\010\n\004WORK\020\002\022\n\n\006CUSTOM\020\003\032M\n\006Avatar\0220\n\006avata" + - "r\030\001 \001(\0132 .signalservice.AttachmentPointe" + - "r\022\021\n\tisProfile\030\002 \001(\010\032V\n\007Preview\022\013\n\003url\030\001" + - " \001(\t\022\r\n\005title\030\002 \001(\t\022/\n\005image\030\003 \001(\0132 .sig" + - "nalservice.AttachmentPointer\032:\n\013LokiProf" + - "ile\022\023\n\013displayName\030\001 \001(\t\022\026\n\016profilePictu" + - "re\030\002 \001(\t\032\221\004\n\031ClosedGroupControlMessage\022G" + - "\n\004type\030\001 \002(\01629.signalservice.DataMessage" + - ".ClosedGroupControlMessage.Type\022\021\n\tpubli", - "cKey\030\002 \001(\014\022\014\n\004name\030\003 \001(\t\0221\n\021encryptionKe" + - "yPair\030\004 \001(\0132\026.signalservice.KeyPair\022\017\n\007m" + - "embers\030\005 \003(\014\022\016\n\006admins\030\006 \003(\014\022U\n\010wrappers" + - "\030\007 \003(\0132C.signalservice.DataMessage.Close" + - "dGroupControlMessage.KeyPairWrapper\032=\n\016K" + - "eyPairWrapper\022\021\n\tpublicKey\030\001 \002(\014\022\030\n\020encr" + - "yptedKeyPair\030\002 \002(\014\"\237\001\n\004Type\022\007\n\003NEW\020\001\022\n\n\006" + - "UPDATE\020\002\022\027\n\023ENCRYPTION_KEY_PAIR\020\003\022\017\n\013NAM" + - "E_CHANGE\020\004\022\021\n\rMEMBERS_ADDED\020\005\022\023\n\017MEMBERS" + - "_REMOVED\020\006\022\017\n\013MEMBER_LEFT\020\007\022\037\n\033ENCRYPTIO", - "N_KEY_PAIR_REQUEST\020\010\"$\n\005Flags\022\033\n\027EXPIRAT" + - "ION_TIMER_UPDATE\020\002\"\316\003\n\024ConfigurationMess" + - "age\022E\n\014closedGroups\030\001 \003(\0132/.signalservic" + - "e.ConfigurationMessage.ClosedGroup\022\022\n\nop" + - "enGroups\030\002 \003(\t\022\023\n\013displayName\030\003 \001(\t\022\026\n\016p" + - "rofilePicture\030\004 \001(\t\022\022\n\nprofileKey\030\005 \001(\014\022" + - "=\n\010contacts\030\006 \003(\0132+.signalservice.Config" + - "urationMessage.Contact\032\202\001\n\013ClosedGroup\022\021" + - "\n\tpublicKey\030\001 \001(\014\022\014\n\004name\030\002 \001(\t\0221\n\021encry" + - "ptionKeyPair\030\003 \001(\0132\026.signalservice.KeyPa", - "ir\022\017\n\007members\030\004 \003(\014\022\016\n\006admins\030\005 \003(\014\032V\n\007C" + - "ontact\022\021\n\tpublicKey\030\001 \002(\014\022\014\n\004name\030\002 \002(\t\022" + - "\026\n\016profilePicture\030\003 \001(\t\022\022\n\nprofileKey\030\004 " + - "\001(\014\"u\n\016ReceiptMessage\0220\n\004type\030\001 \001(\0162\".si" + - "gnalservice.ReceiptMessage.Type\022\021\n\ttimes" + - "tamp\030\002 \003(\004\"\036\n\004Type\022\014\n\010DELIVERY\020\000\022\010\n\004READ" + - "\020\001\"\354\001\n\021AttachmentPointer\022\n\n\002id\030\001 \001(\006\022\023\n\013" + - "contentType\030\002 \001(\t\022\013\n\003key\030\003 \001(\014\022\014\n\004size\030\004" + - " \001(\r\022\021\n\tthumbnail\030\005 \001(\014\022\016\n\006digest\030\006 \001(\014\022" + - "\020\n\010fileName\030\007 \001(\t\022\r\n\005flags\030\010 \001(\r\022\r\n\005widt", - "h\030\t \001(\r\022\016\n\006height\030\n \001(\r\022\017\n\007caption\030\013 \001(\t" + - "\022\013\n\003url\030e \001(\t\"\032\n\005Flags\022\021\n\rVOICE_MESSAGE\020" + - "\001\"\243\002\n\014GroupContext\022\n\n\002id\030\001 \001(\014\022.\n\004type\030\002" + - " \001(\0162 .signalservice.GroupContext.Type\022\014" + - "\n\004name\030\003 \001(\t\022\017\n\007members\030\004 \003(\t\0220\n\006avatar\030" + - "\005 \001(\0132 .signalservice.AttachmentPointer\022" + - "\016\n\006admins\030\006 \003(\t\022\023\n\nnewMembers\030\346\007 \003(\t\022\027\n\016" + - "removedMembers\030\347\007 \003(\t\"H\n\004Type\022\013\n\007UNKNOWN" + - "\020\000\022\n\n\006UPDATE\020\001\022\013\n\007DELIVER\020\002\022\010\n\004QUIT\020\003\022\020\n" + - "\014REQUEST_INFO\020\004\"\356\001\n\016ContactDetails\022\016\n\006nu", - "mber\030\001 \001(\t\022\014\n\004name\030\002 \001(\t\0224\n\006avatar\030\003 \001(\013" + - "2$.signalservice.ContactDetails.Avatar\022\r" + - "\n\005color\030\004 \001(\t\022\022\n\nprofileKey\030\006 \001(\014\022\017\n\007blo" + - "cked\030\007 \001(\010\022\023\n\013expireTimer\030\010 \001(\r\022\020\n\010nickn" + - "ame\030e \001(\t\032-\n\006Avatar\022\023\n\013contentType\030\001 \001(\t" + - "\022\016\n\006length\030\002 \001(\r\"\367\001\n\014GroupDetails\022\n\n\002id\030" + - "\001 \001(\014\022\014\n\004name\030\002 \001(\t\022\017\n\007members\030\003 \003(\t\0222\n\006" + - "avatar\030\004 \001(\0132\".signalservice.GroupDetail" + - "s.Avatar\022\024\n\006active\030\005 \001(\010:\004true\022\023\n\013expire" + - "Timer\030\006 \001(\r\022\r\n\005color\030\007 \001(\t\022\017\n\007blocked\030\010 ", - "\001(\010\022\016\n\006admins\030\t \003(\t\032-\n\006Avatar\022\023\n\013content" + - "Type\030\001 \001(\t\022\016\n\006length\030\002 \001(\r\"\"\n\016PublicChat" + - "Info\022\020\n\010serverID\030\001 \001(\004BB\n+org.session.li" + - "bsignal.service.internal.pushB\023SignalSer" + - "viceProtos" + "evice\030\007 \001(\r\022\021\n\ttimestamp\030\005 \002(\004\022\017\n\007conten" + + "t\030\010 \001(\014\022\027\n\017serverTimestamp\030\n \001(\004\"5\n\004Type" + + "\022\023\n\017SESSION_MESSAGE\020\006\022\030\n\024CLOSED_GROUP_ME" + + "SSAGE\020\007\"{\n\rTypingMessage\022\021\n\ttimestamp\030\001 " + + "\002(\004\0223\n\006action\030\002 \002(\0162#.signalservice.Typi" + + "ngMessage.Action\"\"\n\006Action\022\013\n\007STARTED\020\000\022" + + "\013\n\007STOPPED\020\001\"\270\002\n\007Content\022/\n\013dataMessage\030", + "\001 \001(\0132\032.signalservice.DataMessage\0225\n\016rec" + + "eiptMessage\030\005 \001(\0132\035.signalservice.Receip" + + "tMessage\0223\n\rtypingMessage\030\006 \001(\0132\034.signal" + + "service.TypingMessage\022A\n\024configurationMe" + + "ssage\030\007 \001(\0132#.signalservice.Configuratio" + + "nMessage\022M\n\032dataExtractionNotification\030R" + + " \001(\0132).signalservice.DataExtractionNotif" + + "ication\"0\n\007KeyPair\022\021\n\tpublicKey\030\001 \002(\014\022\022\n" + + "\nprivateKey\030\002 \002(\014\"\226\001\n\032DataExtractionNoti" + + "fication\022<\n\004type\030\001 \002(\0162..signalservice.D", + "ataExtractionNotification.Type\022\021\n\ttimest" + + "amp\030\002 \001(\004\"\'\n\004Type\022\016\n\nSCREENSHOT\020\001\022\017\n\013MED" + + "IA_SAVED\020\002\"\215\013\n\013DataMessage\022\014\n\004body\030\001 \001(\t" + + "\0225\n\013attachments\030\002 \003(\0132 .signalservice.At" + + "tachmentPointer\022*\n\005group\030\003 \001(\0132\033.signals" + + "ervice.GroupContext\022\r\n\005flags\030\004 \001(\r\022\023\n\013ex" + + "pireTimer\030\005 \001(\r\022\022\n\nprofileKey\030\006 \001(\014\022\021\n\tt" + + "imestamp\030\007 \001(\004\022/\n\005quote\030\010 \001(\0132 .signalse" + + "rvice.DataMessage.Quote\0223\n\007preview\030\n \003(\013" + + "2\".signalservice.DataMessage.Preview\0227\n\007", + "profile\030e \001(\0132&.signalservice.DataMessag" + + "e.LokiProfile\022W\n\031closedGroupControlMessa" + + "ge\030h \001(\01324.signalservice.DataMessage.Clo" + + "sedGroupControlMessage\022\022\n\nsyncTarget\030i \001" + + "(\t\032\225\002\n\005Quote\022\n\n\002id\030\001 \002(\004\022\016\n\006author\030\002 \002(\t" + + "\022\014\n\004text\030\003 \001(\t\022F\n\013attachments\030\004 \003(\01321.si" + + "gnalservice.DataMessage.Quote.QuotedAtta" + + "chment\032\231\001\n\020QuotedAttachment\022\023\n\013contentTy" + + "pe\030\001 \001(\t\022\020\n\010fileName\030\002 \001(\t\0223\n\tthumbnail\030" + + "\003 \001(\0132 .signalservice.AttachmentPointer\022", + "\r\n\005flags\030\004 \001(\r\"\032\n\005Flags\022\021\n\rVOICE_MESSAGE" + + "\020\001\032V\n\007Preview\022\013\n\003url\030\001 \002(\t\022\r\n\005title\030\002 \001(" + + "\t\022/\n\005image\030\003 \001(\0132 .signalservice.Attachm" + + "entPointer\032:\n\013LokiProfile\022\023\n\013displayName" + + "\030\001 \001(\t\022\026\n\016profilePicture\030\002 \001(\t\032\343\003\n\031Close" + + "dGroupControlMessage\022G\n\004type\030\001 \002(\01629.sig" + + "nalservice.DataMessage.ClosedGroupContro" + + "lMessage.Type\022\021\n\tpublicKey\030\002 \001(\014\022\014\n\004name" + + "\030\003 \001(\t\0221\n\021encryptionKeyPair\030\004 \001(\0132\026.sign" + + "alservice.KeyPair\022\017\n\007members\030\005 \003(\014\022\016\n\006ad", + "mins\030\006 \003(\014\022U\n\010wrappers\030\007 \003(\0132C.signalser" + + "vice.DataMessage.ClosedGroupControlMessa" + + "ge.KeyPairWrapper\032=\n\016KeyPairWrapper\022\021\n\tp" + + "ublicKey\030\001 \002(\014\022\030\n\020encryptedKeyPair\030\002 \002(\014" + + "\"r\n\004Type\022\007\n\003NEW\020\001\022\027\n\023ENCRYPTION_KEY_PAIR" + + "\020\003\022\017\n\013NAME_CHANGE\020\004\022\021\n\rMEMBERS_ADDED\020\005\022\023" + + "\n\017MEMBERS_REMOVED\020\006\022\017\n\013MEMBER_LEFT\020\007\"$\n\005" + + "Flags\022\033\n\027EXPIRATION_TIMER_UPDATE\020\002\"\316\003\n\024C" + + "onfigurationMessage\022E\n\014closedGroups\030\001 \003(" + + "\0132/.signalservice.ConfigurationMessage.C", + "losedGroup\022\022\n\nopenGroups\030\002 \003(\t\022\023\n\013displa" + + "yName\030\003 \001(\t\022\026\n\016profilePicture\030\004 \001(\t\022\022\n\np" + + "rofileKey\030\005 \001(\014\022=\n\010contacts\030\006 \003(\0132+.sign" + + "alservice.ConfigurationMessage.Contact\032\202" + + "\001\n\013ClosedGroup\022\021\n\tpublicKey\030\001 \001(\014\022\014\n\004nam" + + "e\030\002 \001(\t\0221\n\021encryptionKeyPair\030\003 \001(\0132\026.sig" + + "nalservice.KeyPair\022\017\n\007members\030\004 \003(\014\022\016\n\006a" + + "dmins\030\005 \003(\014\032V\n\007Contact\022\021\n\tpublicKey\030\001 \002(" + + "\014\022\014\n\004name\030\002 \002(\t\022\026\n\016profilePicture\030\003 \001(\t\022" + + "\022\n\nprofileKey\030\004 \001(\014\"u\n\016ReceiptMessage\0220\n", + "\004type\030\001 \002(\0162\".signalservice.ReceiptMessa" + + "ge.Type\022\021\n\ttimestamp\030\002 \003(\004\"\036\n\004Type\022\014\n\010DE" + + "LIVERY\020\000\022\010\n\004READ\020\001\"\354\001\n\021AttachmentPointer" + + "\022\n\n\002id\030\001 \002(\006\022\023\n\013contentType\030\002 \001(\t\022\013\n\003key" + + "\030\003 \001(\014\022\014\n\004size\030\004 \001(\r\022\021\n\tthumbnail\030\005 \001(\014\022" + + "\016\n\006digest\030\006 \001(\014\022\020\n\010fileName\030\007 \001(\t\022\r\n\005fla" + + "gs\030\010 \001(\r\022\r\n\005width\030\t \001(\r\022\016\n\006height\030\n \001(\r\022" + + "\017\n\007caption\030\013 \001(\t\022\013\n\003url\030e \001(\t\"\032\n\005Flags\022\021" + + "\n\rVOICE_MESSAGE\020\001\"\365\001\n\014GroupContext\022\n\n\002id" + + "\030\001 \001(\014\022.\n\004type\030\002 \001(\0162 .signalservice.Gro", + "upContext.Type\022\014\n\004name\030\003 \001(\t\022\017\n\007members\030" + + "\004 \003(\t\0220\n\006avatar\030\005 \001(\0132 .signalservice.At" + + "tachmentPointer\022\016\n\006admins\030\006 \003(\t\"H\n\004Type\022" + + "\013\n\007UNKNOWN\020\000\022\n\n\006UPDATE\020\001\022\013\n\007DELIVER\020\002\022\010\n" + + "\004QUIT\020\003\022\020\n\014REQUEST_INFO\020\004BB\n+org.session" + + ".libsignal.service.internal.pushB\023Signal" + + "ServiceProtos" }; com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { @@ -33511,30 +20349,24 @@ public final class SignalServiceProtos { com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_signalservice_Content_descriptor, new java.lang.String[] { "DataMessage", "ReceiptMessage", "TypingMessage", "ConfigurationMessage", "DataExtractionNotification", }); - internal_static_signalservice_ClosedGroupCiphertextMessageWrapper_descriptor = - getDescriptor().getMessageTypes().get(3); - internal_static_signalservice_ClosedGroupCiphertextMessageWrapper_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signalservice_ClosedGroupCiphertextMessageWrapper_descriptor, - new java.lang.String[] { "Ciphertext", "EphemeralPublicKey", }); internal_static_signalservice_KeyPair_descriptor = - getDescriptor().getMessageTypes().get(4); + getDescriptor().getMessageTypes().get(3); internal_static_signalservice_KeyPair_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_signalservice_KeyPair_descriptor, new java.lang.String[] { "PublicKey", "PrivateKey", }); internal_static_signalservice_DataExtractionNotification_descriptor = - getDescriptor().getMessageTypes().get(5); + getDescriptor().getMessageTypes().get(4); internal_static_signalservice_DataExtractionNotification_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_signalservice_DataExtractionNotification_descriptor, new java.lang.String[] { "Type", "Timestamp", }); internal_static_signalservice_DataMessage_descriptor = - getDescriptor().getMessageTypes().get(6); + getDescriptor().getMessageTypes().get(5); internal_static_signalservice_DataMessage_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_signalservice_DataMessage_descriptor, - new java.lang.String[] { "Body", "Attachments", "Group", "Flags", "ExpireTimer", "ProfileKey", "Timestamp", "Quote", "Contact", "Preview", "Profile", "ClosedGroupControlMessage", "SyncTarget", "PublicChatInfo", }); + new java.lang.String[] { "Body", "Attachments", "Group", "Flags", "ExpireTimer", "ProfileKey", "Timestamp", "Quote", "Preview", "Profile", "ClosedGroupControlMessage", "SyncTarget", }); internal_static_signalservice_DataMessage_Quote_descriptor = internal_static_signalservice_DataMessage_descriptor.getNestedTypes().get(0); internal_static_signalservice_DataMessage_Quote_fieldAccessorTable = new @@ -33547,56 +20379,20 @@ public final class SignalServiceProtos { com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_signalservice_DataMessage_Quote_QuotedAttachment_descriptor, new java.lang.String[] { "ContentType", "FileName", "Thumbnail", "Flags", }); - internal_static_signalservice_DataMessage_Contact_descriptor = - internal_static_signalservice_DataMessage_descriptor.getNestedTypes().get(1); - internal_static_signalservice_DataMessage_Contact_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signalservice_DataMessage_Contact_descriptor, - new java.lang.String[] { "Name", "Number", "Email", "Address", "Avatar", "Organization", }); - internal_static_signalservice_DataMessage_Contact_Name_descriptor = - internal_static_signalservice_DataMessage_Contact_descriptor.getNestedTypes().get(0); - internal_static_signalservice_DataMessage_Contact_Name_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signalservice_DataMessage_Contact_Name_descriptor, - new java.lang.String[] { "GivenName", "FamilyName", "Prefix", "Suffix", "MiddleName", "DisplayName", }); - internal_static_signalservice_DataMessage_Contact_Phone_descriptor = - internal_static_signalservice_DataMessage_Contact_descriptor.getNestedTypes().get(1); - internal_static_signalservice_DataMessage_Contact_Phone_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signalservice_DataMessage_Contact_Phone_descriptor, - new java.lang.String[] { "Value", "Type", "Label", }); - internal_static_signalservice_DataMessage_Contact_Email_descriptor = - internal_static_signalservice_DataMessage_Contact_descriptor.getNestedTypes().get(2); - internal_static_signalservice_DataMessage_Contact_Email_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signalservice_DataMessage_Contact_Email_descriptor, - new java.lang.String[] { "Value", "Type", "Label", }); - internal_static_signalservice_DataMessage_Contact_PostalAddress_descriptor = - internal_static_signalservice_DataMessage_Contact_descriptor.getNestedTypes().get(3); - internal_static_signalservice_DataMessage_Contact_PostalAddress_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signalservice_DataMessage_Contact_PostalAddress_descriptor, - new java.lang.String[] { "Type", "Label", "Street", "Pobox", "Neighborhood", "City", "Region", "Postcode", "Country", }); - internal_static_signalservice_DataMessage_Contact_Avatar_descriptor = - internal_static_signalservice_DataMessage_Contact_descriptor.getNestedTypes().get(4); - internal_static_signalservice_DataMessage_Contact_Avatar_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signalservice_DataMessage_Contact_Avatar_descriptor, - new java.lang.String[] { "Avatar", "IsProfile", }); internal_static_signalservice_DataMessage_Preview_descriptor = - internal_static_signalservice_DataMessage_descriptor.getNestedTypes().get(2); + internal_static_signalservice_DataMessage_descriptor.getNestedTypes().get(1); internal_static_signalservice_DataMessage_Preview_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_signalservice_DataMessage_Preview_descriptor, new java.lang.String[] { "Url", "Title", "Image", }); internal_static_signalservice_DataMessage_LokiProfile_descriptor = - internal_static_signalservice_DataMessage_descriptor.getNestedTypes().get(3); + internal_static_signalservice_DataMessage_descriptor.getNestedTypes().get(2); internal_static_signalservice_DataMessage_LokiProfile_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_signalservice_DataMessage_LokiProfile_descriptor, new java.lang.String[] { "DisplayName", "ProfilePicture", }); internal_static_signalservice_DataMessage_ClosedGroupControlMessage_descriptor = - internal_static_signalservice_DataMessage_descriptor.getNestedTypes().get(4); + internal_static_signalservice_DataMessage_descriptor.getNestedTypes().get(3); internal_static_signalservice_DataMessage_ClosedGroupControlMessage_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_signalservice_DataMessage_ClosedGroupControlMessage_descriptor, @@ -33608,7 +20404,7 @@ public final class SignalServiceProtos { internal_static_signalservice_DataMessage_ClosedGroupControlMessage_KeyPairWrapper_descriptor, new java.lang.String[] { "PublicKey", "EncryptedKeyPair", }); internal_static_signalservice_ConfigurationMessage_descriptor = - getDescriptor().getMessageTypes().get(7); + getDescriptor().getMessageTypes().get(6); internal_static_signalservice_ConfigurationMessage_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_signalservice_ConfigurationMessage_descriptor, @@ -33626,53 +20422,23 @@ public final class SignalServiceProtos { internal_static_signalservice_ConfigurationMessage_Contact_descriptor, new java.lang.String[] { "PublicKey", "Name", "ProfilePicture", "ProfileKey", }); internal_static_signalservice_ReceiptMessage_descriptor = - getDescriptor().getMessageTypes().get(8); + getDescriptor().getMessageTypes().get(7); internal_static_signalservice_ReceiptMessage_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_signalservice_ReceiptMessage_descriptor, new java.lang.String[] { "Type", "Timestamp", }); internal_static_signalservice_AttachmentPointer_descriptor = - getDescriptor().getMessageTypes().get(9); + getDescriptor().getMessageTypes().get(8); internal_static_signalservice_AttachmentPointer_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_signalservice_AttachmentPointer_descriptor, new java.lang.String[] { "Id", "ContentType", "Key", "Size", "Thumbnail", "Digest", "FileName", "Flags", "Width", "Height", "Caption", "Url", }); internal_static_signalservice_GroupContext_descriptor = - getDescriptor().getMessageTypes().get(10); + getDescriptor().getMessageTypes().get(9); internal_static_signalservice_GroupContext_fieldAccessorTable = new com.google.protobuf.GeneratedMessage.FieldAccessorTable( internal_static_signalservice_GroupContext_descriptor, - new java.lang.String[] { "Id", "Type", "Name", "Members", "Avatar", "Admins", "NewMembers", "RemovedMembers", }); - internal_static_signalservice_ContactDetails_descriptor = - getDescriptor().getMessageTypes().get(11); - internal_static_signalservice_ContactDetails_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signalservice_ContactDetails_descriptor, - new java.lang.String[] { "Number", "Name", "Avatar", "Color", "ProfileKey", "Blocked", "ExpireTimer", "Nickname", }); - internal_static_signalservice_ContactDetails_Avatar_descriptor = - internal_static_signalservice_ContactDetails_descriptor.getNestedTypes().get(0); - internal_static_signalservice_ContactDetails_Avatar_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signalservice_ContactDetails_Avatar_descriptor, - new java.lang.String[] { "ContentType", "Length", }); - internal_static_signalservice_GroupDetails_descriptor = - getDescriptor().getMessageTypes().get(12); - internal_static_signalservice_GroupDetails_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signalservice_GroupDetails_descriptor, - new java.lang.String[] { "Id", "Name", "Members", "Avatar", "Active", "ExpireTimer", "Color", "Blocked", "Admins", }); - internal_static_signalservice_GroupDetails_Avatar_descriptor = - internal_static_signalservice_GroupDetails_descriptor.getNestedTypes().get(0); - internal_static_signalservice_GroupDetails_Avatar_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signalservice_GroupDetails_Avatar_descriptor, - new java.lang.String[] { "ContentType", "Length", }); - internal_static_signalservice_PublicChatInfo_descriptor = - getDescriptor().getMessageTypes().get(13); - internal_static_signalservice_PublicChatInfo_fieldAccessorTable = new - com.google.protobuf.GeneratedMessage.FieldAccessorTable( - internal_static_signalservice_PublicChatInfo_descriptor, - new java.lang.String[] { "ServerID", }); + new java.lang.String[] { "Id", "Type", "Name", "Members", "Avatar", "Admins", }); return null; } }; From 17e764fc31df0640abdf6d567d7d3d59900e866d Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Mon, 26 Apr 2021 11:14:45 +1000 Subject: [PATCH 06/13] Clean --- .../securesms/ApplicationContext.java | 8 +-- .../conversation/ConversationFragment.java | 2 +- .../conversation/ConversationItem.java | 2 +- .../securesms/database/Storage.kt | 12 ++-- .../database/model/MessageRecord.java | 14 ++--- .../database/model/ThreadRecord.java | 2 - .../securesms/loki/activities/HomeActivity.kt | 2 +- .../loki/activities/SettingsActivity.kt | 4 +- .../loki/api/BackgroundPollWorker.kt | 3 +- .../securesms/loki/api/PublicChatManager.kt | 10 ++-- .../loki/protocol/MultiDeviceProtocol.kt | 4 +- .../loki/utilities/OpenGroupUtilities.kt | 4 +- .../loki/views/MentionCandidateView.kt | 2 +- .../securesms/mms/PushMediaConstraints.java | 2 +- .../messaging/MessagingConfiguration.kt | 25 -------- .../messaging/MessagingModuleConfiguration.kt | 26 +++++++++ .../libsession/messaging/StorageProtocol.kt | 3 +- .../avatars/GroupRecordContactPhoto.java | 4 +- .../FileServerAPI.kt | 3 +- .../messaging/jobs/AttachmentDownloadJob.kt | 12 ++-- .../messaging/jobs/AttachmentUploadJob.kt | 16 ++--- .../libsession/messaging/jobs/JobQueue.kt | 12 ++-- .../messaging/jobs/MessageSendJob.kt | 8 +-- .../messaging/messages/Destination.kt | 6 +- .../libsession/messaging/messages/Message.kt | 2 - .../control/ClosedGroupControlMessage.kt | 4 +- .../messages/control/ConfigurationMessage.kt | 8 ++- .../control/DataExtractionNotification.kt | 5 +- .../messages/control/ExpirationTimerUpdate.kt | 7 +-- .../messaging/messages/control/ReadReceipt.kt | 3 - .../messages/control/TypingIndicator.kt | 11 +--- .../messages/signal/IncomingGroupMessage.java | 2 - .../messaging/messages/visible/Attachment.kt | 3 +- .../messaging/messages/visible/Contact.kt | 17 ------ .../messaging/messages/visible/LinkPreview.kt | 8 +-- .../messaging/messages/visible/Profile.kt | 2 - .../messaging/messages/visible/Quote.kt | 7 +-- .../messages/visible/VisibleMessage.kt | 13 ++--- .../{opengroups => open_groups}/OpenGroup.kt | 2 +- .../OpenGroupAPI.kt | 15 +++-- .../OpenGroupInfo.kt | 2 +- .../OpenGroupMessage.kt | 10 ++-- .../sending_receiving/MessageReceiver.kt | 10 ++-- .../MessageReceiverDecryption.kt | 4 +- .../MessageReceiverHandler.kt | 58 +++++++++---------- .../sending_receiving/MessageSender.kt | 24 ++++---- .../MessageSenderClosedGroup.kt | 30 +++++----- .../MessageSenderEncryption.kt | 4 +- .../attachments/DatabaseAttachment.java | 6 +- .../notifications/PushNotificationAPI.kt | 10 ++-- .../pollers/ClosedGroupPoller.kt | 6 +- .../pollers/OpenGroupPoller.kt | 18 +++--- .../sending_receiving/pollers/Poller.kt | 4 +- .../messaging/threads/GroupRecord.kt | 1 + .../threads/recipients/Recipient.java | 4 +- .../threads/recipients/RecipientProvider.java | 8 +-- ....kt => ClosedGroupUpdateMessageBuilder.kt} | 27 +++++---- ...ata.kt => ClosedGroupUpdateMessageData.kt} | 20 +++---- .../messaging/utilities/DotNetAPI.kt | 15 +++-- .../libsession/snode/OnionRequestAPI.kt | 2 +- 60 files changed, 250 insertions(+), 308 deletions(-) delete mode 100644 libsession/src/main/java/org/session/libsession/messaging/MessagingConfiguration.kt create mode 100644 libsession/src/main/java/org/session/libsession/messaging/MessagingModuleConfiguration.kt rename libsession/src/main/java/org/session/libsession/messaging/{fileserver => file_server}/FileServerAPI.kt (97%) delete mode 100644 libsession/src/main/java/org/session/libsession/messaging/messages/visible/Contact.kt rename libsession/src/main/java/org/session/libsession/messaging/{opengroups => open_groups}/OpenGroup.kt (96%) rename libsession/src/main/java/org/session/libsession/messaging/{opengroups => open_groups}/OpenGroupAPI.kt (97%) rename libsession/src/main/java/org/session/libsession/messaging/{opengroups => open_groups}/OpenGroupInfo.kt (69%) rename libsession/src/main/java/org/session/libsession/messaging/{opengroups => open_groups}/OpenGroupMessage.kt (95%) rename libsession/src/main/java/org/session/libsession/messaging/utilities/{UpdateMessageBuilder.kt => ClosedGroupUpdateMessageBuilder.kt} (80%) rename libsession/src/main/java/org/session/libsession/messaging/utilities/{UpdateMessageData.kt => ClosedGroupUpdateMessageData.kt} (70%) diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 38de09d0e0..6156e80f2f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -30,10 +30,10 @@ import androidx.lifecycle.ProcessLifecycleOwner; import androidx.multidex.MultiDexApplication; import org.conscrypt.Conscrypt; -import org.session.libsession.messaging.MessagingConfiguration; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.messaging.avatars.AvatarHelper; import org.session.libsession.messaging.jobs.JobQueue; -import org.session.libsession.messaging.opengroups.OpenGroupAPI; +import org.session.libsession.messaging.open_groups.OpenGroupAPI; import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier; import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPoller; import org.session.libsession.messaging.sending_receiving.pollers.Poller; @@ -169,7 +169,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc LokiThreadDatabase threadDB = DatabaseFactory.getLokiThreadDatabase(this); LokiUserDatabase userDB = DatabaseFactory.getLokiUserDatabase(this); String userPublicKey = TextSecurePreferences.getLocalNumber(this); - MessagingConfiguration.Companion.configure(this, + MessagingModuleConfiguration.Companion.configure(this, DatabaseFactory.getStorage(this), DatabaseFactory.getAttachmentProvider(this), new SessionProtocolImpl(this)); @@ -420,7 +420,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc } byte[] userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(this).getPrivateKey().serialize(); LokiAPIDatabaseProtocol apiDB = DatabaseFactory.getLokiAPIDatabase(this); - org.session.libsession.messaging.fileserver.FileServerAPI.Companion.configure(userPublicKey, userPrivateKey, apiDB); + org.session.libsession.messaging.file_server.FileServerAPI.Companion.configure(userPublicKey, userPrivateKey, apiDB); return true; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java index 2aedad1119..b487f52716 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java @@ -60,7 +60,7 @@ import com.annimon.stream.Stream; import org.session.libsession.messaging.messages.control.DataExtractionNotification; import org.session.libsession.messaging.messages.visible.Quote; import org.session.libsession.messaging.messages.visible.VisibleMessage; -import org.session.libsession.messaging.opengroups.OpenGroupAPI; +import org.session.libsession.messaging.open_groups.OpenGroupAPI; import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.MessageDetailsActivity; import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity; diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java index 46601321db..314b5e723c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java @@ -54,7 +54,7 @@ import com.annimon.stream.Stream; import org.session.libsession.messaging.jobs.AttachmentDownloadJob; import org.session.libsession.messaging.jobs.JobQueue; -import org.session.libsession.messaging.opengroups.OpenGroupAPI; +import org.session.libsession.messaging.open_groups.OpenGroupAPI; import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress; import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment; import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; 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 0a58ac42fd..91e11037f0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -2,7 +2,6 @@ package org.thoughtcrime.securesms.database import android.content.Context import android.net.Uri -import com.google.protobuf.ByteString import org.session.libsession.messaging.StorageProtocol import org.session.libsession.messaging.jobs.AttachmentUploadJob import org.session.libsession.messaging.jobs.Job @@ -13,7 +12,7 @@ import org.session.libsession.messaging.messages.signal.* import org.session.libsession.messaging.messages.signal.IncomingTextMessage import org.session.libsession.messaging.messages.visible.Attachment import org.session.libsession.messaging.messages.visible.VisibleMessage -import org.session.libsession.messaging.opengroups.OpenGroup +import org.session.libsession.messaging.open_groups.OpenGroup import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage @@ -23,8 +22,7 @@ import org.session.libsession.messaging.threads.Address import org.session.libsession.messaging.threads.Address.Companion.fromSerialized import org.session.libsession.messaging.threads.GroupRecord import org.session.libsession.messaging.threads.recipients.Recipient -import org.session.libsession.messaging.utilities.UpdateMessageBuilder -import org.session.libsession.messaging.utilities.UpdateMessageData +import org.session.libsession.messaging.utilities.ClosedGroupUpdateMessageData import org.session.libsession.utilities.GroupUtil import org.session.libsession.utilities.IdentityKeyUtil import org.session.libsession.utilities.TextSecurePreferences @@ -34,7 +32,6 @@ import org.session.libsignal.libsignal.util.KeyHelper import org.session.libsignal.libsignal.util.guava.Optional import org.session.libsignal.service.api.messages.SignalServiceAttachmentPointer import org.session.libsignal.service.api.messages.SignalServiceGroup -import org.session.libsignal.service.internal.push.SignalServiceProtos import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper import org.thoughtcrime.securesms.jobs.RetrieveProfileAvatarJob @@ -44,7 +41,6 @@ import org.thoughtcrime.securesms.loki.utilities.OpenGroupUtilities import org.thoughtcrime.securesms.loki.utilities.get import org.thoughtcrime.securesms.loki.utilities.getString import org.thoughtcrime.securesms.mms.PartAuthority -import java.util.* class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), StorageProtocol { override fun getUserPublicKey(): String? { @@ -406,7 +402,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, override fun insertIncomingInfoMessage(context: Context, senderPublicKey: String, groupID: String, type: SignalServiceGroup.Type, name: String, members: Collection, admins: Collection, sentTimestamp: Long) { val group = SignalServiceGroup(type, GroupUtil.getDecodedGroupIDAsData(groupID), SignalServiceGroup.GroupType.SIGNAL, name, members.toList(), null, admins.toList()) val m = IncomingTextMessage(Address.fromSerialized(senderPublicKey), 1, sentTimestamp, "", Optional.of(group), 0, true) - val updateData = UpdateMessageData.buildGroupUpdate(type, name, members)?.toJSON() + val updateData = ClosedGroupUpdateMessageData.buildGroupUpdate(type, name, members)?.toJSON() val infoMessage = IncomingGroupMessage(m, groupID, updateData, true) val smsDB = DatabaseFactory.getSmsDatabase(context) smsDB.insertMessageInbox(infoMessage) @@ -416,7 +412,7 @@ class Storage(context: Context, helper: SQLCipherOpenHelper) : Database(context, val userPublicKey = getUserPublicKey() val recipient = Recipient.from(context, Address.fromSerialized(groupID), false) - val updateData = UpdateMessageData.buildGroupUpdate(type, name, members)?.toJSON() ?: "" + val updateData = ClosedGroupUpdateMessageData.buildGroupUpdate(type, name, members)?.toJSON() ?: "" val infoMessage = OutgoingGroupMediaMessage(recipient, updateData, groupID, null, sentTimestamp, 0, true, null, listOf(), listOf()) val mmsDB = DatabaseFactory.getMmsDatabase(context) val mmsSmsDB = DatabaseFactory.getMmsSmsDatabase(context) 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 9ecb9bac2e..55b8642827 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 @@ -26,8 +26,8 @@ import android.text.style.StyleSpan; import network.loki.messenger.R; import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage; -import org.session.libsession.messaging.utilities.UpdateMessageBuilder; -import org.session.libsession.messaging.utilities.UpdateMessageData; +import org.session.libsession.messaging.utilities.ClosedGroupUpdateMessageBuilder; +import org.session.libsession.messaging.utilities.ClosedGroupUpdateMessageData; import org.thoughtcrime.securesms.database.MmsSmsColumns; import org.thoughtcrime.securesms.database.SmsDatabase; import org.session.libsession.database.documents.IdentityKeyMismatch; @@ -93,14 +93,14 @@ public abstract class MessageRecord extends DisplayRecord { @Override public SpannableString getDisplayBody(@NonNull Context context) { if(isGroupUpdateMessage()) { - UpdateMessageData updateMessageData = UpdateMessageData.Companion.fromJSON(getBody()); - return new SpannableString(UpdateMessageBuilder.INSTANCE.buildGroupUpdateMessage(context, updateMessageData, getIndividualRecipient().getAddress().serialize(), isOutgoing())); + ClosedGroupUpdateMessageData updateMessageData = ClosedGroupUpdateMessageData.Companion.fromJSON(getBody()); + return new SpannableString(ClosedGroupUpdateMessageBuilder.INSTANCE.buildGroupUpdateMessage(context, updateMessageData, getIndividualRecipient().getAddress().serialize(), isOutgoing())); } else if (isExpirationTimerUpdate()) { int seconds = (int) (getExpiresIn() / 1000); - return new SpannableString(UpdateMessageBuilder.INSTANCE.buildExpirationTimerMessage(context, seconds, getIndividualRecipient().getAddress().serialize(), isOutgoing())); + return new SpannableString(ClosedGroupUpdateMessageBuilder.INSTANCE.buildExpirationTimerMessage(context, seconds, getIndividualRecipient().getAddress().serialize(), isOutgoing())); } else if (isDataExtraction()) { - if (isScreenshotExtraction()) return new SpannableString((UpdateMessageBuilder.INSTANCE.buildDataExtractionMessage(context, DataExtractionNotificationInfoMessage.Kind.SCREENSHOT, getIndividualRecipient().getAddress().serialize()))); - else if (isMediaSavedExtraction()) return new SpannableString((UpdateMessageBuilder.INSTANCE.buildDataExtractionMessage(context, DataExtractionNotificationInfoMessage.Kind.MEDIA_SAVED, getIndividualRecipient().getAddress().serialize()))); + if (isScreenshotExtraction()) return new SpannableString((ClosedGroupUpdateMessageBuilder.INSTANCE.buildDataExtractionMessage(context, DataExtractionNotificationInfoMessage.Kind.SCREENSHOT, getIndividualRecipient().getAddress().serialize()))); + else if (isMediaSavedExtraction()) return new SpannableString((ClosedGroupUpdateMessageBuilder.INSTANCE.buildDataExtractionMessage(context, DataExtractionNotificationInfoMessage.Kind.MEDIA_SAVED, getIndividualRecipient().getAddress().serialize()))); } // TODO below lines are left here for compatibility with older group update messages, it can be deleted later on else if (isGroupUpdate() && isOutgoing()) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/ThreadRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/ThreadRecord.java index 3315ba94f2..b0183cff63 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/ThreadRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/ThreadRecord.java @@ -28,8 +28,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.session.libsession.messaging.threads.recipients.Recipient; -import org.session.libsession.messaging.utilities.UpdateMessageBuilder; -import org.session.libsession.messaging.utilities.UpdateMessageData; import org.session.libsession.utilities.ExpirationUtil; import org.thoughtcrime.securesms.database.MmsSmsColumns; import org.thoughtcrime.securesms.database.SmsDatabase; diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt index 8ed97bf3e2..a8ed5f2c74 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt @@ -30,7 +30,7 @@ import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode import org.session.libsession.messaging.jobs.JobQueue -import org.session.libsession.messaging.opengroups.OpenGroupAPI +import org.session.libsession.messaging.open_groups.OpenGroupAPI import org.session.libsession.messaging.sending_receiving.MessageSender import org.session.libsession.utilities.* import org.session.libsignal.service.loki.utilities.mentions.MentionsManager diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/SettingsActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/SettingsActivity.kt index 95d1f446c0..c046fd9115 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/SettingsActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/SettingsActivity.kt @@ -28,8 +28,8 @@ import nl.komponents.kovenant.functional.bind import nl.komponents.kovenant.task import nl.komponents.kovenant.ui.alwaysUi import org.session.libsession.messaging.avatars.AvatarHelper -import org.session.libsession.messaging.fileserver.FileServerAPI -import org.session.libsession.messaging.opengroups.OpenGroupAPI +import org.session.libsession.messaging.file_server.FileServerAPI +import org.session.libsession.messaging.open_groups.OpenGroupAPI import org.session.libsession.messaging.threads.Address import org.session.libsession.utilities.SSKEnvironment.ProfileManagerProtocol import org.session.libsession.utilities.TextSecurePreferences diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt index d4bd5ed8d4..9622750503 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt @@ -7,8 +7,7 @@ import androidx.work.* import nl.komponents.kovenant.Promise import nl.komponents.kovenant.all import nl.komponents.kovenant.functional.map -import org.session.libsession.messaging.jobs.MessageReceiveJob -import org.session.libsession.messaging.opengroups.OpenGroup +import org.session.libsession.messaging.open_groups.OpenGroup import org.session.libsession.messaging.sending_receiving.pollers.OpenGroupPoller import org.session.libsession.snode.SnodeAPI import org.session.libsession.utilities.TextSecurePreferences diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/api/PublicChatManager.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/api/PublicChatManager.kt index c2200ac0a7..a7726bfee3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/api/PublicChatManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/api/PublicChatManager.kt @@ -5,10 +5,10 @@ import android.database.ContentObserver import android.graphics.Bitmap import android.text.TextUtils import androidx.annotation.WorkerThread -import org.session.libsession.messaging.MessagingConfiguration -import org.session.libsession.messaging.opengroups.OpenGroup -import org.session.libsession.messaging.opengroups.OpenGroupAPI -import org.session.libsession.messaging.opengroups.OpenGroupInfo +import org.session.libsession.messaging.MessagingModuleConfiguration +import org.session.libsession.messaging.open_groups.OpenGroup +import org.session.libsession.messaging.open_groups.OpenGroupAPI +import org.session.libsession.messaging.open_groups.OpenGroupInfo import org.session.libsession.messaging.sending_receiving.pollers.OpenGroupPoller import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.Util @@ -110,7 +110,7 @@ class PublicChatManager(private val context: Context) { } private fun refreshChatsAndPollers() { - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage val chatsInDB = storage.getAllOpenGroups() val removedChatThreadIds = chats.keys.filter { !chatsInDB.keys.contains(it) } removedChatThreadIds.forEach { pollers.remove(it)?.stop() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt index 41b3de72f8..7b699c0780 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/MultiDeviceProtocol.kt @@ -2,7 +2,7 @@ package org.thoughtcrime.securesms.loki.protocol import android.content.Context import com.google.protobuf.ByteString -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.messages.Destination import org.session.libsession.messaging.messages.control.ConfigurationMessage import org.session.libsession.messaging.sending_receiving.MessageSender @@ -63,7 +63,7 @@ object MultiDeviceProtocol { val configurationMessage = ConfigurationMessage.fromProto(content) ?: return - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage val allClosedGroupPublicKeys = storage.getAllClosedGroupPublicKeys() val threadDatabase = DatabaseFactory.getThreadDatabase(context) diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/OpenGroupUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/OpenGroupUtilities.kt index c6b789f996..9f5bad1f00 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/OpenGroupUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/OpenGroupUtilities.kt @@ -3,8 +3,8 @@ package org.thoughtcrime.securesms.loki.utilities import android.content.Context import androidx.annotation.WorkerThread import org.greenrobot.eventbus.EventBus -import org.session.libsession.messaging.opengroups.OpenGroup -import org.session.libsession.messaging.opengroups.OpenGroupAPI +import org.session.libsession.messaging.open_groups.OpenGroup +import org.session.libsession.messaging.open_groups.OpenGroupAPI import org.session.libsession.utilities.GroupUtil import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.preferences.ProfileKeyUtil diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateView.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateView.kt index f85e5e9867..f7af85ed13 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/views/MentionCandidateView.kt @@ -8,7 +8,7 @@ import android.view.ViewGroup import android.widget.LinearLayout import kotlinx.android.synthetic.main.view_mention_candidate.view.* import network.loki.messenger.R -import org.session.libsession.messaging.opengroups.OpenGroupAPI +import org.session.libsession.messaging.open_groups.OpenGroupAPI import org.session.libsignal.service.loki.utilities.mentions.Mention import org.thoughtcrime.securesms.mms.GlideRequests diff --git a/app/src/main/java/org/thoughtcrime/securesms/mms/PushMediaConstraints.java b/app/src/main/java/org/thoughtcrime/securesms/mms/PushMediaConstraints.java index 4bfcbfd24d..12fc8279f0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mms/PushMediaConstraints.java +++ b/app/src/main/java/org/thoughtcrime/securesms/mms/PushMediaConstraints.java @@ -2,7 +2,7 @@ package org.thoughtcrime.securesms.mms; import android.content.Context; -import org.session.libsession.messaging.fileserver.FileServerAPI; +import org.session.libsession.messaging.file_server.FileServerAPI; public class PushMediaConstraints extends MediaConstraints { diff --git a/libsession/src/main/java/org/session/libsession/messaging/MessagingConfiguration.kt b/libsession/src/main/java/org/session/libsession/messaging/MessagingConfiguration.kt deleted file mode 100644 index ae1daec5a6..0000000000 --- a/libsession/src/main/java/org/session/libsession/messaging/MessagingConfiguration.kt +++ /dev/null @@ -1,25 +0,0 @@ -package org.session.libsession.messaging - -import android.content.Context -import org.session.libsession.database.MessageDataProvider -import org.session.libsignal.service.loki.api.crypto.SessionProtocol - -class MessagingConfiguration( - val context: Context, - val storage: StorageProtocol, - val messageDataProvider: MessageDataProvider, - val sessionProtocol: SessionProtocol) -{ - companion object { - lateinit var shared: MessagingConfiguration - - fun configure(context: Context, - storage: StorageProtocol, - messageDataProvider: MessageDataProvider, - sessionProtocol: SessionProtocol - ) { - if (Companion::shared.isInitialized) { return } - shared = MessagingConfiguration(context, storage, messageDataProvider, sessionProtocol) - } - } -} \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/MessagingModuleConfiguration.kt b/libsession/src/main/java/org/session/libsession/messaging/MessagingModuleConfiguration.kt new file mode 100644 index 0000000000..e6ec434c9d --- /dev/null +++ b/libsession/src/main/java/org/session/libsession/messaging/MessagingModuleConfiguration.kt @@ -0,0 +1,26 @@ +package org.session.libsession.messaging + +import android.content.Context +import org.session.libsession.database.MessageDataProvider +import org.session.libsignal.service.loki.api.crypto.SessionProtocol + +class MessagingModuleConfiguration( + val context: Context, + val storage: StorageProtocol, + val messageDataProvider: MessageDataProvider, + val sessionProtocol: SessionProtocol) +{ + + companion object { + lateinit var shared: MessagingModuleConfiguration + + fun configure(context: Context, + storage: StorageProtocol, + messageDataProvider: MessageDataProvider, + sessionProtocol: SessionProtocol + ) { + if (Companion::shared.isInitialized) { return } + shared = MessagingModuleConfiguration(context, storage, messageDataProvider, sessionProtocol) + } + } +} \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt b/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt index da84c8f6e8..f1f8d8c49c 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt @@ -9,7 +9,7 @@ import org.session.libsession.messaging.jobs.MessageSendJob import org.session.libsession.messaging.messages.control.ConfigurationMessage import org.session.libsession.messaging.messages.visible.Attachment import org.session.libsession.messaging.messages.visible.VisibleMessage -import org.session.libsession.messaging.opengroups.OpenGroup +import org.session.libsession.messaging.open_groups.OpenGroup import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment @@ -21,7 +21,6 @@ import org.session.libsession.messaging.threads.recipients.Recipient.RecipientSe import org.session.libsignal.libsignal.ecc.ECKeyPair import org.session.libsignal.service.api.messages.SignalServiceAttachmentPointer import org.session.libsignal.service.api.messages.SignalServiceGroup -import org.session.libsignal.service.internal.push.SignalServiceProtos interface StorageProtocol { diff --git a/libsession/src/main/java/org/session/libsession/messaging/avatars/GroupRecordContactPhoto.java b/libsession/src/main/java/org/session/libsession/messaging/avatars/GroupRecordContactPhoto.java index 24c2dfec93..7967368e1f 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/avatars/GroupRecordContactPhoto.java +++ b/libsession/src/main/java/org/session/libsession/messaging/avatars/GroupRecordContactPhoto.java @@ -6,7 +6,7 @@ import android.net.Uri; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.session.libsession.messaging.MessagingConfiguration; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.messaging.StorageProtocol; import org.session.libsession.messaging.threads.Address; import org.session.libsession.messaging.threads.GroupRecord; @@ -31,7 +31,7 @@ public class GroupRecordContactPhoto implements ContactPhoto { @Override public InputStream openInputStream(Context context) throws IOException { - StorageProtocol groupDatabase = MessagingConfiguration.shared.getStorage(); + StorageProtocol groupDatabase = MessagingModuleConfiguration.shared.getStorage(); Optional groupRecord = Optional.of(groupDatabase.getGroup(address.toGroupString())); if (groupRecord.isPresent() && groupRecord.get().getAvatar() != null) { diff --git a/libsession/src/main/java/org/session/libsession/messaging/fileserver/FileServerAPI.kt b/libsession/src/main/java/org/session/libsession/messaging/file_server/FileServerAPI.kt similarity index 97% rename from libsession/src/main/java/org/session/libsession/messaging/fileserver/FileServerAPI.kt rename to libsession/src/main/java/org/session/libsession/messaging/file_server/FileServerAPI.kt index c0ae724d44..5e78caf6f0 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/fileserver/FileServerAPI.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/file_server/FileServerAPI.kt @@ -1,4 +1,4 @@ -package org.session.libsession.messaging.fileserver +package org.session.libsession.messaging.file_server import nl.komponents.kovenant.Promise import nl.komponents.kovenant.functional.map @@ -11,7 +11,6 @@ import org.session.libsignal.utilities.JsonUtil import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol import org.session.libsignal.service.loki.utilities.* import java.net.URL -import java.util.concurrent.ConcurrentHashMap class FileServerAPI(public val server: String, userPublicKey: String, userPrivateKey: ByteArray, private val database: LokiAPIDatabaseProtocol) : DotNetAPI() { diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt index a1e3077de7..557d161667 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentDownloadJob.kt @@ -1,7 +1,7 @@ package org.session.libsession.messaging.jobs -import org.session.libsession.messaging.MessagingConfiguration -import org.session.libsession.messaging.fileserver.FileServerAPI +import org.session.libsession.messaging.MessagingModuleConfiguration +import org.session.libsession.messaging.file_server.FileServerAPI import org.session.libsession.messaging.sending_receiving.attachments.AttachmentState import org.session.libsession.messaging.utilities.DotNetAPI import org.session.libsignal.service.api.crypto.AttachmentCipherInputStream @@ -33,19 +33,19 @@ class AttachmentDownloadJob(val attachmentID: Long, val databaseMessageID: Long) override fun execute() { val handleFailure: (java.lang.Exception) -> Unit = { exception -> if (exception == Error.NoAttachment) { - MessagingConfiguration.shared.messageDataProvider.setAttachmentState(AttachmentState.FAILED, attachmentID, databaseMessageID) + MessagingModuleConfiguration.shared.messageDataProvider.setAttachmentState(AttachmentState.FAILED, attachmentID, databaseMessageID) this.handlePermanentFailure(exception) } else if (exception == DotNetAPI.Error.ParsingFailed) { // No need to retry if the response is invalid. Most likely this means we (incorrectly) // got a "Cannot GET ..." error from the file server. - MessagingConfiguration.shared.messageDataProvider.setAttachmentState(AttachmentState.FAILED, attachmentID, databaseMessageID) + MessagingModuleConfiguration.shared.messageDataProvider.setAttachmentState(AttachmentState.FAILED, attachmentID, databaseMessageID) this.handlePermanentFailure(exception) } else { this.handleFailure(exception) } } try { - val messageDataProvider = MessagingConfiguration.shared.messageDataProvider + val messageDataProvider = MessagingModuleConfiguration.shared.messageDataProvider val attachment = messageDataProvider.getDatabaseAttachment(attachmentID) ?: return handleFailure(Error.NoAttachment) messageDataProvider.setAttachmentState(AttachmentState.STARTED, attachmentID, this.databaseMessageID) val tempFile = createTempFile() @@ -79,7 +79,7 @@ class AttachmentDownloadJob(val attachmentID: Long, val databaseMessageID: Long) } private fun createTempFile(): File { - val file = File.createTempFile("push-attachment", "tmp", MessagingConfiguration.shared.context.cacheDir) + val file = File.createTempFile("push-attachment", "tmp", MessagingModuleConfiguration.shared.context.cacheDir) file.deleteOnExit() return file } diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentUploadJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentUploadJob.kt index f05a3bcf81..ffdf459693 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentUploadJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/AttachmentUploadJob.kt @@ -3,8 +3,8 @@ package org.session.libsession.messaging.jobs import com.esotericsoftware.kryo.Kryo import com.esotericsoftware.kryo.io.Input import com.esotericsoftware.kryo.io.Output -import org.session.libsession.messaging.MessagingConfiguration -import org.session.libsession.messaging.fileserver.FileServerAPI +import org.session.libsession.messaging.MessagingModuleConfiguration +import org.session.libsession.messaging.file_server.FileServerAPI import org.session.libsession.messaging.messages.Message import org.session.libsession.messaging.sending_receiving.MessageSender import org.session.libsession.messaging.utilities.DotNetAPI @@ -42,11 +42,11 @@ class AttachmentUploadJob(val attachmentID: Long, val threadID: String, val mess override fun execute() { try { - val attachment = MessagingConfiguration.shared.messageDataProvider.getScaledSignalAttachmentStream(attachmentID) + val attachment = MessagingModuleConfiguration.shared.messageDataProvider.getScaledSignalAttachmentStream(attachmentID) ?: return handleFailure(Error.NoAttachment) val usePadding = false - val openGroup = MessagingConfiguration.shared.storage.getOpenGroup(threadID) + val openGroup = MessagingModuleConfiguration.shared.storage.getOpenGroup(threadID) val server = if (openGroup != null) openGroup.server else FileServerAPI.shared.server val shouldEncrypt = (openGroup == null) // Encrypt if this isn't an open group @@ -74,14 +74,14 @@ class AttachmentUploadJob(val attachmentID: Long, val threadID: String, val mess private fun handleSuccess(attachment: SignalServiceAttachmentStream, attachmentKey: ByteArray, uploadResult: DotNetAPI.UploadResult) { Log.w(TAG, "Attachment uploaded successfully.") delegate?.handleJobSucceeded(this) - MessagingConfiguration.shared.messageDataProvider.updateAttachmentAfterUploadSucceeded(attachmentID, attachment, attachmentKey, uploadResult) - MessagingConfiguration.shared.storage.resumeMessageSendJobIfNeeded(messageSendJobID) + MessagingModuleConfiguration.shared.messageDataProvider.updateAttachmentAfterUploadSucceeded(attachmentID, attachment, attachmentKey, uploadResult) + MessagingModuleConfiguration.shared.storage.resumeMessageSendJobIfNeeded(messageSendJobID) } private fun handlePermanentFailure(e: Exception) { Log.w(TAG, "Attachment upload failed permanently due to error: $this.") delegate?.handleJobFailedPermanently(this, e) - MessagingConfiguration.shared.messageDataProvider.updateAttachmentAfterUploadFailed(attachmentID) + MessagingModuleConfiguration.shared.messageDataProvider.updateAttachmentAfterUploadFailed(attachmentID) failAssociatedMessageSendJob(e) } @@ -94,7 +94,7 @@ class AttachmentUploadJob(val attachmentID: Long, val threadID: String, val mess } private fun failAssociatedMessageSendJob(e: Exception) { - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage val messageSendJob = storage.getMessageSendJob(messageSendJobID) MessageSender.handleFailedMessageSend(this.message, e) if (messageSendJob != null) { diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/JobQueue.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/JobQueue.kt index 9e8e1374dc..ae9e5d4b35 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/JobQueue.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/JobQueue.kt @@ -3,7 +3,7 @@ package org.session.libsession.messaging.jobs import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsignal.utilities.logging.Log import java.util.* import java.util.concurrent.ConcurrentHashMap @@ -54,7 +54,7 @@ class JobQueue : JobDelegate { jobTimestampMap.putIfAbsent(currentTime, AtomicInteger()) job.id = currentTime.toString() + jobTimestampMap[currentTime]!!.getAndIncrement().toString() - MessagingConfiguration.shared.storage.persistJob(job) + MessagingModuleConfiguration.shared.storage.persistJob(job) } fun resumePendingJobs() { @@ -65,7 +65,7 @@ class JobQueue : JobDelegate { hasResumedPendingJobs = true val allJobTypes = listOf(AttachmentDownloadJob.KEY, AttachmentDownloadJob.KEY, MessageReceiveJob.KEY, MessageSendJob.KEY, NotifyPNServerJob.KEY) allJobTypes.forEach { type -> - val allPendingJobs = MessagingConfiguration.shared.storage.getAllPendingJobs(type) + val allPendingJobs = MessagingModuleConfiguration.shared.storage.getAllPendingJobs(type) allPendingJobs.sortedBy { it.id }.forEach { job -> Log.i("Jobs", "Resuming pending job of type: ${job::class.simpleName}.") queue.offer(job) // Offer always called on unlimited capacity @@ -74,12 +74,12 @@ class JobQueue : JobDelegate { } override fun handleJobSucceeded(job: Job) { - MessagingConfiguration.shared.storage.markJobAsSucceeded(job) + MessagingModuleConfiguration.shared.storage.markJobAsSucceeded(job) } override fun handleJobFailed(job: Job, error: Exception) { job.failureCount += 1 - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage if (storage.isJobCanceled(job)) { return Log.i("Jobs", "${job::class.simpleName} canceled.")} storage.persistJob(job) if (job.failureCount == job.maxFailureCount) { @@ -96,7 +96,7 @@ class JobQueue : JobDelegate { override fun handleJobFailedPermanently(job: Job, error: Exception) { job.failureCount += 1 - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage storage.persistJob(job) storage.markJobAsFailed(job) } diff --git a/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageSendJob.kt b/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageSendJob.kt index 066ab85b2e..c695df8311 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageSendJob.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/jobs/MessageSendJob.kt @@ -3,7 +3,7 @@ package org.session.libsession.messaging.jobs import com.esotericsoftware.kryo.Kryo import com.esotericsoftware.kryo.io.Input import com.esotericsoftware.kryo.io.Output -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.messages.Destination import org.session.libsession.messaging.messages.Message import org.session.libsession.messaging.messages.visible.VisibleMessage @@ -27,7 +27,7 @@ class MessageSendJob(val message: Message, val destination: Destination) : Job { } override fun execute() { - val messageDataProvider = MessagingConfiguration.shared.messageDataProvider + val messageDataProvider = MessagingModuleConfiguration.shared.messageDataProvider val message = message as? VisibleMessage message?.let { if(!messageDataProvider.isOutgoingMessage(message.sentTimestamp!!)) return // The message has been deleted @@ -38,7 +38,7 @@ class MessageSendJob(val message: Message, val destination: Destination) : Job { val attachments = attachmentIDs.mapNotNull { messageDataProvider.getDatabaseAttachment(it) } val attachmentsToUpload = attachments.filter { it.url.isNullOrEmpty() } attachmentsToUpload.forEach { - if (MessagingConfiguration.shared.storage.getAttachmentUploadJob(it.attachmentId.rowId) != null) { + if (MessagingModuleConfiguration.shared.storage.getAttachmentUploadJob(it.attachmentId.rowId) != null) { // Wait for it to finish } else { val job = AttachmentUploadJob(it.attachmentId.rowId, message.threadID!!.toString(), message, id!!) @@ -71,7 +71,7 @@ class MessageSendJob(val message: Message, val destination: Destination) : Job { Log.w(TAG, "Failed to send $message::class.simpleName.") val message = message as? VisibleMessage message?.let { - if(!MessagingConfiguration.shared.messageDataProvider.isOutgoingMessage(message.sentTimestamp!!)) return // The message has been deleted + if(!MessagingModuleConfiguration.shared.messageDataProvider.isOutgoingMessage(message.sentTimestamp!!)) return // The message has been deleted } delegate?.handleJobFailed(this, error) } diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/Destination.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/Destination.kt index ef389b08b0..250479ec93 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/Destination.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/Destination.kt @@ -1,6 +1,6 @@ package org.session.libsession.messaging.messages -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.threads.Address import org.session.libsession.utilities.GroupUtil import org.session.libsignal.service.loki.utilities.toHexString @@ -29,8 +29,8 @@ sealed class Destination { ClosedGroup(groupPublicKey) } address.isOpenGroup -> { - val threadID = MessagingConfiguration.shared.storage.getThreadID(address.contactIdentifier())!! - val openGroup = MessagingConfiguration.shared.storage.getOpenGroup(threadID)!! + val threadID = MessagingModuleConfiguration.shared.storage.getThreadID(address.contactIdentifier())!! + val openGroup = MessagingModuleConfiguration.shared.storage.getOpenGroup(threadID)!! OpenGroup(openGroup.channel, openGroup.server) } else -> { diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt index ef60aaa83e..d6204dc123 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/Message.kt @@ -5,7 +5,6 @@ import org.session.libsession.utilities.GroupUtil import org.session.libsignal.service.internal.push.SignalServiceProtos abstract class Message { - var id: Long? = null var threadID: Long? = null var sentTimestamp: Long? = null @@ -18,7 +17,6 @@ abstract class Message { open val ttl: Long = 14 * 24 * 60 * 60 * 1000 open val isSelfSendValid: Boolean = false - // validation open fun isValid(): Boolean { sentTimestamp?.let { if (it <= 0) return false diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupControlMessage.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupControlMessage.kt index 83c223b1ac..75af2abd6a 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupControlMessage.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ClosedGroupControlMessage.kt @@ -1,7 +1,7 @@ package org.session.libsession.messaging.messages.control import com.google.protobuf.ByteString -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.threads.Address import org.session.libsession.messaging.threads.recipients.Recipient import org.session.libsession.utilities.GroupUtil @@ -172,7 +172,7 @@ class ClosedGroupControlMessage() : ControlMessage() { // Expiration timer // TODO: We * want * expiration timer updates to be explicit. But currently Android will disable the expiration timer for a conversation // if it receives a message without the current expiration timer value attached to it... - dataMessageProto.expireTimer = Recipient.from(MessagingConfiguration.shared.context, Address.fromSerialized(GroupUtil.doubleEncodeGroupID(recipient!!)), false).expireMessages + dataMessageProto.expireTimer = Recipient.from(MessagingModuleConfiguration.shared.context, Address.fromSerialized(GroupUtil.doubleEncodeGroupID(recipient!!)), false).expireMessages contentProto.dataMessage = dataMessageProto.build() return contentProto.build() } catch (e: Exception) { diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ConfigurationMessage.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ConfigurationMessage.kt index 2fbf13588f..29aa13e586 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ConfigurationMessage.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ConfigurationMessage.kt @@ -1,7 +1,7 @@ package org.session.libsession.messaging.messages.control import com.google.protobuf.ByteString -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.threads.Address import org.session.libsession.utilities.GroupUtil import org.session.libsession.utilities.TextSecurePreferences @@ -26,13 +26,14 @@ class ConfigurationMessage(var closedGroups: List, var openGroups: } companion object { + fun fromProto(proto: SignalServiceProtos.ConfigurationMessage.ClosedGroup): ClosedGroup? { if (!proto.hasPublicKey() || !proto.hasName() || !proto.hasEncryptionKeyPair()) return null val publicKey = proto.publicKey.toByteArray().toHexString() val name = proto.name val encryptionKeyPairAsProto = proto.encryptionKeyPair val encryptionKeyPair = ECKeyPair(DjbECPublicKey(encryptionKeyPairAsProto.publicKey.toByteArray().removing05PrefixIfNeeded()), - DjbECPrivateKey(encryptionKeyPairAsProto.privateKey.toByteArray())) + DjbECPrivateKey(encryptionKeyPairAsProto.privateKey.toByteArray())) val members = proto.membersList.map { it.toByteArray().toHexString() } val admins = proto.adminsList.map { it.toByteArray().toHexString() } return ClosedGroup(publicKey, name, encryptionKeyPair, members, admins) @@ -58,6 +59,7 @@ class ConfigurationMessage(var closedGroups: List, var openGroups: internal constructor(): this("", "", null, null) companion object { + fun fromProto(proto: SignalServiceProtos.ConfigurationMessage.Contact): Contact? { if (!proto.hasName() || !proto.hasProfileKey()) return null val publicKey = proto.publicKey.toByteArray().toHexString() @@ -94,7 +96,7 @@ class ConfigurationMessage(var closedGroups: List, var openGroups: fun getCurrent(contacts: List): ConfigurationMessage? { val closedGroups = mutableListOf() val openGroups = mutableListOf() - val sharedConfig = MessagingConfiguration.shared + val sharedConfig = MessagingModuleConfiguration.shared val storage = sharedConfig.storage val context = sharedConfig.context val displayName = TextSecurePreferences.getProfileName(context) ?: return null diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/DataExtractionNotification.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/DataExtractionNotification.kt index 538b0b0001..5aec11827b 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/DataExtractionNotification.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/DataExtractionNotification.kt @@ -6,13 +6,12 @@ import org.session.libsignal.utilities.logging.Log class DataExtractionNotification(): ControlMessage() { var kind: Kind? = null - // Kind enum sealed class Kind { class Screenshot() : Kind() class MediaSaved(val timestamp: Long) : Kind() val description: String = - when(this) { + when (this) { is Screenshot -> "screenshot" is MediaSaved -> "mediaSaved" } @@ -35,12 +34,10 @@ class DataExtractionNotification(): ControlMessage() { } } - //constructor internal constructor(kind: Kind) : this() { this.kind = kind } - // MARK: Validation override fun isValid(): Boolean { if (!super.isValid()) return false val kind = kind ?: return false diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ExpirationTimerUpdate.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ExpirationTimerUpdate.kt index 5dff39072c..5d1854e815 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ExpirationTimerUpdate.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ExpirationTimerUpdate.kt @@ -1,12 +1,11 @@ package org.session.libsession.messaging.messages.control -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.messages.visible.VisibleMessage import org.session.libsignal.utilities.logging.Log import org.session.libsignal.service.internal.push.SignalServiceProtos class ExpirationTimerUpdate() : ControlMessage() { - /// In the case of a sync message, the public key of the person the message was targeted at. /// - Note: `nil` if this isn't a sync message. var syncTarget: String? = null @@ -27,7 +26,6 @@ class ExpirationTimerUpdate() : ControlMessage() { } } - //constructor internal constructor(syncTarget: String?, duration: Int) : this() { this.syncTarget = syncTarget this.duration = duration @@ -38,7 +36,6 @@ class ExpirationTimerUpdate() : ControlMessage() { this.duration = duration } - // validation override fun isValid(): Boolean { if (!super.isValid()) return false return duration != null @@ -58,7 +55,7 @@ class ExpirationTimerUpdate() : ControlMessage() { dataMessageProto.syncTarget = syncTarget } // Group context - if (MessagingConfiguration.shared.storage.isClosedGroup(recipient!!)) { + if (MessagingModuleConfiguration.shared.storage.isClosedGroup(recipient!!)) { try { setGroupContext(dataMessageProto) } catch(e: Exception) { diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ReadReceipt.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ReadReceipt.kt index d842e079f9..a912740da0 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/ReadReceipt.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/ReadReceipt.kt @@ -4,7 +4,6 @@ import org.session.libsignal.service.internal.push.SignalServiceProtos import org.session.libsignal.utilities.logging.Log class ReadReceipt() : ControlMessage() { - var timestamps: List? = null companion object { @@ -19,12 +18,10 @@ class ReadReceipt() : ControlMessage() { } } - //constructor internal constructor(timestamps: List?) : this() { this.timestamps = timestamps } - // validation override fun isValid(): Boolean { if (!super.isValid()) return false val timestamps = timestamps ?: return false diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/control/TypingIndicator.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/control/TypingIndicator.kt index 8bbfd727bb..dd26ae7031 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/control/TypingIndicator.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/control/TypingIndicator.kt @@ -4,8 +4,8 @@ import org.session.libsignal.service.internal.push.SignalServiceProtos import org.session.libsignal.utilities.logging.Log class TypingIndicator() : ControlMessage() { - override val ttl: Long = 30 * 1000 + var kind: Kind? = null companion object { const val TAG = "TypingIndicator" @@ -17,11 +17,8 @@ class TypingIndicator() : ControlMessage() { } } - // Kind enum enum class Kind { - STARTED, - STOPPED, - ; + STARTED, STOPPED; companion object { @JvmStatic @@ -40,14 +37,10 @@ class TypingIndicator() : ControlMessage() { } } - var kind: Kind? = null - - //constructor internal constructor(kind: Kind) : this() { this.kind = kind } - // validation override fun isValid(): Boolean { if (!super.isValid()) return false return kind != null diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/signal/IncomingGroupMessage.java b/libsession/src/main/java/org/session/libsession/messaging/messages/signal/IncomingGroupMessage.java index 125267afb7..213f815ded 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/signal/IncomingGroupMessage.java +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/signal/IncomingGroupMessage.java @@ -1,7 +1,5 @@ package org.session.libsession.messaging.messages.signal; -import static org.session.libsignal.service.internal.push.SignalServiceProtos.GroupContext; - public class IncomingGroupMessage extends IncomingTextMessage { private final String groupID; diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Attachment.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Attachment.kt index c7c6a670e6..1630502671 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Attachment.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Attachment.kt @@ -11,7 +11,6 @@ import org.session.libsignal.service.internal.push.SignalServiceProtos import java.io.File class Attachment { - var fileName: String? = null var contentType: String? = null var key: ByteArray? = null @@ -23,6 +22,7 @@ class Attachment { var url: String? = null companion object { + fun fromProto(proto: SignalServiceProtos.AttachmentPointer): Attachment { val result = Attachment() result.fileName = proto.fileName @@ -88,7 +88,6 @@ class Attachment { GENERIC } - // validation fun isValid(): Boolean { // key and digest can be nil for open group attachments return (contentType != null && kind != null && size != null && sizeInBytes != null && url != null) diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Contact.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Contact.kt deleted file mode 100644 index 1b959e5e03..0000000000 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Contact.kt +++ /dev/null @@ -1,17 +0,0 @@ -package org.session.libsession.messaging.messages.visible - -import org.session.libsession.database.MessageDataProvider -import org.session.libsignal.service.internal.push.SignalServiceProtos - -class Contact() { - - companion object { - fun fromProto(proto: SignalServiceProtos.Content): Contact? { - TODO("Not yet implemented") - } - } - - fun toProto(): SignalServiceProtos.DataMessage.Contact? { - TODO("Not yet implemented") - } -} \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/LinkPreview.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/LinkPreview.kt index ddfb397173..63395bb155 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/LinkPreview.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/LinkPreview.kt @@ -1,12 +1,11 @@ package org.session.libsession.messaging.messages.visible -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview as SignalLinkPreiview import org.session.libsignal.utilities.logging.Log import org.session.libsignal.service.internal.push.SignalServiceProtos class LinkPreview() { - var title: String? = null var url: String? = null var attachmentID: Long? = 0 @@ -29,15 +28,12 @@ class LinkPreview() { } } - //constructor internal constructor(title: String?, url: String, attachmentID: Long?) : this() { this.title = title this.url = url this.attachmentID = attachmentID } - - // validation fun isValid(): Boolean { return (title != null && url != null && attachmentID != null) } @@ -53,7 +49,7 @@ class LinkPreview() { title?.let { linkPreviewProto.title = title } val attachmentID = attachmentID attachmentID?.let { - MessagingConfiguration.shared.messageDataProvider.getSignalAttachmentPointer(attachmentID)?.let { + MessagingModuleConfiguration.shared.messageDataProvider.getSignalAttachmentPointer(attachmentID)?.let { val attachmentProto = Attachment.createAttachmentPointer(it) linkPreviewProto.image = attachmentProto } diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Profile.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Profile.kt index 49cc97dce4..7464a4be5d 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Profile.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Profile.kt @@ -5,7 +5,6 @@ import org.session.libsignal.utilities.logging.Log import org.session.libsignal.service.internal.push.SignalServiceProtos class Profile() { - var displayName: String? = null var profileKey: ByteArray? = null var profilePictureURL: String? = null @@ -27,7 +26,6 @@ class Profile() { } } - //constructor internal constructor(displayName: String, profileKey: ByteArray? = null, profilePictureURL: String? = null) : this() { this.displayName = displayName this.profileKey = profileKey diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Quote.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Quote.kt index e1255c6ef0..88bf089a1c 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Quote.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/Quote.kt @@ -1,14 +1,13 @@ package org.session.libsession.messaging.messages.visible import com.goterl.lazycode.lazysodium.BuildConfig -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel as SignalQuote import org.session.libsignal.utilities.logging.Log import org.session.libsignal.service.internal.push.SignalServiceProtos class Quote() { - var timestamp: Long? = 0 var publicKey: String? = null var text: String? = null @@ -34,7 +33,6 @@ class Quote() { } } - //constructor internal constructor(timestamp: Long, publicKey: String, text: String?, attachmentID: Long?) : this() { this.timestamp = timestamp this.publicKey = publicKey @@ -42,7 +40,6 @@ class Quote() { this.attachmentID = attachmentID } - // validation fun isValid(): Boolean { return (timestamp != null && publicKey != null) } @@ -70,7 +67,7 @@ class Quote() { private fun addAttachmentsIfNeeded(quoteProto: SignalServiceProtos.DataMessage.Quote.Builder) { if (attachmentID == null) return - val attachment = MessagingConfiguration.shared.messageDataProvider.getSignalAttachmentPointer(attachmentID!!) + val attachment = MessagingModuleConfiguration.shared.messageDataProvider.getSignalAttachmentPointer(attachmentID!!) if (attachment == null) { Log.w(TAG, "Ignoring invalid attachment for quoted message.") return diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/VisibleMessage.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/VisibleMessage.kt index 0b2c4b59e8..63756c0948 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/VisibleMessage.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/VisibleMessage.kt @@ -1,7 +1,7 @@ package org.session.libsession.messaging.messages.visible import com.goterl.lazycode.lazysodium.BuildConfig -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.messages.Message import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment import org.session.libsession.messaging.threads.Address @@ -12,13 +12,11 @@ import org.session.libsignal.utilities.logging.Log import org.session.libsession.messaging.sending_receiving.attachments.Attachment as SignalAttachment class VisibleMessage : Message() { - var syncTarget: String? = null var text: String? = null val attachmentIDs: MutableList = mutableListOf() var quote: Quote? = null var linkPreview: LinkPreview? = null - var contact: Contact? = null var profile: Profile? = null override val isSelfSendValid: Boolean = true @@ -60,10 +58,9 @@ class VisibleMessage : Message() { } fun isMediaMessage(): Boolean { - return attachmentIDs.isNotEmpty() || quote != null || linkPreview != null || contact != null + return attachmentIDs.isNotEmpty() || quote != null || linkPreview != null } - // validation override fun isValid(): Boolean { if (!super.isValid()) return false if (attachmentIDs.isNotEmpty()) return true @@ -98,7 +95,7 @@ class VisibleMessage : Message() { } } //Attachments - val attachments = attachmentIDs.mapNotNull { MessagingConfiguration.shared.messageDataProvider.getSignalAttachmentPointer(it) } + val attachments = attachmentIDs.mapNotNull { MessagingModuleConfiguration.shared.messageDataProvider.getSignalAttachmentPointer(it) } if (!attachments.all { !it.url.isNullOrEmpty() }) { if (BuildConfig.DEBUG) { //TODO equivalent to iOS's preconditionFailure @@ -111,8 +108,8 @@ class VisibleMessage : Message() { // Expiration timer // TODO: We * want * expiration timer updates to be explicit. But currently Android will disable the expiration timer for a conversation // if it receives a message without the current expiration timer value attached to it... - val storage = MessagingConfiguration.shared.storage - val context = MessagingConfiguration.shared.context + val storage = MessagingModuleConfiguration.shared.storage + val context = MessagingModuleConfiguration.shared.context val expiration = if (storage.isClosedGroup(recipient!!)) Recipient.from(context, Address.fromSerialized(GroupUtil.doubleEncodeGroupID(recipient!!)), false).expireMessages else Recipient.from(context, Address.fromSerialized(recipient!!), false).expireMessages dataMessage.expireTimer = expiration diff --git a/libsession/src/main/java/org/session/libsession/messaging/opengroups/OpenGroup.kt b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroup.kt similarity index 96% rename from libsession/src/main/java/org/session/libsession/messaging/opengroups/OpenGroup.kt rename to libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroup.kt index c0a48274cd..cf89c9009e 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/opengroups/OpenGroup.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroup.kt @@ -1,4 +1,4 @@ -package org.session.libsession.messaging.opengroups +package org.session.libsession.messaging.open_groups import org.session.libsignal.service.loki.api.opengroups.PublicChat import org.session.libsignal.utilities.JsonUtil diff --git a/libsession/src/main/java/org/session/libsession/messaging/opengroups/OpenGroupAPI.kt b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPI.kt similarity index 97% rename from libsession/src/main/java/org/session/libsession/messaging/opengroups/OpenGroupAPI.kt rename to libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPI.kt index f7b1fd56b2..211bf33643 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/opengroups/OpenGroupAPI.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPI.kt @@ -1,12 +1,11 @@ -package org.session.libsession.messaging.opengroups +package org.session.libsession.messaging.open_groups import nl.komponents.kovenant.Kovenant import nl.komponents.kovenant.Promise import nl.komponents.kovenant.deferred import nl.komponents.kovenant.functional.map import nl.komponents.kovenant.then -import org.session.libsession.messaging.MessagingConfiguration -import org.session.libsession.messaging.fileserver.FileServerAPI +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.utilities.DotNetAPI import org.session.libsignal.service.loki.utilities.retryIfNeeded import org.session.libsignal.utilities.* @@ -51,7 +50,7 @@ object OpenGroupAPI: DotNetAPI() { // region Public API fun getMessages(channel: Long, server: String): Promise, Exception> { Log.d("Loki", "Getting messages for open group with ID: $channel on server: $server.") - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage val parameters = mutableMapOf( "include_annotations" to 1 ) val lastMessageServerID = storage.getLastMessageServerID(channel, server) if (lastMessageServerID != null) { @@ -157,7 +156,7 @@ object OpenGroupAPI: DotNetAPI() { @JvmStatic fun getDeletedMessageServerIDs(channel: Long, server: String): Promise, Exception> { Log.d("Loki", "Getting deleted messages for open group with ID: $channel on server: $server.") - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage val parameters = mutableMapOf() val lastDeletionServerID = storage.getLastDeletionServerID(channel, server) if (lastDeletionServerID != null) { @@ -190,7 +189,7 @@ object OpenGroupAPI: DotNetAPI() { @JvmStatic fun sendMessage(message: OpenGroupMessage, channel: Long, server: String): Promise { val deferred = deferred() - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage val userKeyPair = storage.getUserKeyPair() ?: throw Error.Generic val userDisplayName = storage.getUserDisplayName() ?: throw Error.Generic ThreadUtils.queue { @@ -286,7 +285,7 @@ object OpenGroupAPI: DotNetAPI() { val memberCount = countInfo["subscribers"] as? Int ?: (countInfo["subscribers"] as? Long)?.toInt() ?: (countInfo["subscribers"] as String).toInt() val profilePictureURL = info["avatar"] as String val publicChatInfo = OpenGroupInfo(displayName, profilePictureURL, memberCount) - MessagingConfiguration.shared.storage.setUserCount(channel, server, memberCount) + MessagingModuleConfiguration.shared.storage.setUserCount(channel, server, memberCount) publicChatInfo } catch (exception: Exception) { Log.d("Loki", "Couldn't parse info for open group with ID: $channel on server: $server.") @@ -298,7 +297,7 @@ object OpenGroupAPI: DotNetAPI() { @JvmStatic fun updateProfileIfNeeded(channel: Long, server: String, groupID: String, info: OpenGroupInfo, isForcedUpdate: Boolean) { - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage storage.setUserCount(channel, server, info.memberCount) storage.updateTitle(groupID, info.displayName) // Download and update profile picture if needed diff --git a/libsession/src/main/java/org/session/libsession/messaging/opengroups/OpenGroupInfo.kt b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupInfo.kt similarity index 69% rename from libsession/src/main/java/org/session/libsession/messaging/opengroups/OpenGroupInfo.kt rename to libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupInfo.kt index b02431bf26..6de51187d3 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/opengroups/OpenGroupInfo.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupInfo.kt @@ -1,4 +1,4 @@ -package org.session.libsession.messaging.opengroups +package org.session.libsession.messaging.open_groups data class OpenGroupInfo ( val displayName: String, diff --git a/libsession/src/main/java/org/session/libsession/messaging/opengroups/OpenGroupMessage.kt b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupMessage.kt similarity index 95% rename from libsession/src/main/java/org/session/libsession/messaging/opengroups/OpenGroupMessage.kt rename to libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupMessage.kt index 5a05d0f5f8..492cb4f7c7 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/opengroups/OpenGroupMessage.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupMessage.kt @@ -1,6 +1,6 @@ -package org.session.libsession.messaging.opengroups +package org.session.libsession.messaging.open_groups -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.messages.visible.VisibleMessage import org.session.libsignal.service.loki.utilities.removing05PrefixIfNeeded import org.session.libsignal.utilities.Hex @@ -24,7 +24,7 @@ data class OpenGroupMessage( // region Settings companion object { fun from(message: VisibleMessage, server: String): OpenGroupMessage? { - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage val userPublicKey = storage.getUserPublicKey() ?: return null val attachmentIDs = message.attachmentIDs // Validation @@ -50,7 +50,7 @@ data class OpenGroupMessage( linkPreview?.let { if (!linkPreview.isValid()) { return@let } val attachmentID = linkPreview.attachmentID ?: return@let - val attachment = MessagingConfiguration.shared.messageDataProvider.getSignalAttachmentPointer(attachmentID) ?: return@let + val attachment = MessagingModuleConfiguration.shared.messageDataProvider.getSignalAttachmentPointer(attachmentID) ?: return@let val openGroupLinkPreview = Attachment( Attachment.Kind.LinkPreview, server, @@ -69,7 +69,7 @@ data class OpenGroupMessage( } // Attachments val attachments = message.attachmentIDs.mapNotNull { - val attachment = MessagingConfiguration.shared.messageDataProvider.getSignalAttachmentPointer(it) ?: return@mapNotNull null + val attachment = MessagingModuleConfiguration.shared.messageDataProvider.getSignalAttachmentPointer(it) ?: return@mapNotNull null return@mapNotNull Attachment( Attachment.Kind.Attachment, server, diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiver.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiver.kt index 216d79627c..20d21053fb 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiver.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiver.kt @@ -1,6 +1,6 @@ package org.session.libsession.messaging.sending_receiving -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.messages.Message import org.session.libsession.messaging.messages.control.* import org.session.libsession.messaging.messages.visible.VisibleMessage @@ -44,7 +44,7 @@ object MessageReceiver { } internal fun parse(data: ByteArray, openGroupServerID: Long?, isRetry: Boolean = false): Pair { - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage val userPublicKey = storage.getUserPublicKey() val isOpenGroupMessage = openGroupServerID != null // Parse the envelope @@ -64,17 +64,17 @@ object MessageReceiver { } else { when (envelope.type) { SignalServiceProtos.Envelope.Type.UNIDENTIFIED_SENDER -> { - val userX25519KeyPair = MessagingConfiguration.shared.storage.getUserX25519KeyPair() + val userX25519KeyPair = MessagingModuleConfiguration.shared.storage.getUserX25519KeyPair() val decryptionResult = MessageReceiverDecryption.decryptWithSessionProtocol(ciphertext.toByteArray(), userX25519KeyPair) plaintext = decryptionResult.first sender = decryptionResult.second } SignalServiceProtos.Envelope.Type.CLOSED_GROUP_CIPHERTEXT -> { val hexEncodedGroupPublicKey = envelope.source - if (hexEncodedGroupPublicKey == null || !MessagingConfiguration.shared.storage.isClosedGroup(hexEncodedGroupPublicKey)) { + if (hexEncodedGroupPublicKey == null || !MessagingModuleConfiguration.shared.storage.isClosedGroup(hexEncodedGroupPublicKey)) { throw Error.InvalidGroupPublicKey } - val encryptionKeyPairs = MessagingConfiguration.shared.storage.getClosedGroupEncryptionKeyPairs(hexEncodedGroupPublicKey) + val encryptionKeyPairs = MessagingModuleConfiguration.shared.storage.getClosedGroupEncryptionKeyPairs(hexEncodedGroupPublicKey) if (encryptionKeyPairs.isEmpty()) { throw Error.NoGroupKeyPair } // Loop through all known group key pairs in reverse order (i.e. try the latest key pair first (which'll more than // likely be the one we want) but try older ones in case that didn't work) diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverDecryption.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverDecryption.kt index 2474d75ba5..6c0fb5953e 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverDecryption.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverDecryption.kt @@ -1,11 +1,11 @@ package org.session.libsession.messaging.sending_receiving -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsignal.libsignal.ecc.ECKeyPair object MessageReceiverDecryption { internal fun decryptWithSessionProtocol(ciphertext: ByteArray, x25519KeyPair: ECKeyPair): Pair { - return MessagingConfiguration.shared.sessionProtocol.decrypt(ciphertext, x25519KeyPair) + return MessagingModuleConfiguration.shared.sessionProtocol.decrypt(ciphertext, x25519KeyPair) } } \ No newline at end of file diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt index 567b4ad021..44d3013b13 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt @@ -1,7 +1,7 @@ package org.session.libsession.messaging.sending_receiving import android.text.TextUtils -import org.session.libsession.messaging.MessagingConfiguration +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.messages.Message @@ -35,7 +35,7 @@ import java.util.* import kotlin.collections.ArrayList internal fun MessageReceiver.isBlock(publicKey: String): Boolean { - val context = MessagingConfiguration.shared.context + val context = MessagingModuleConfiguration.shared.context val recipient = Recipient.from(context, Address.fromSerialized(publicKey), false) return recipient.isBlocked } @@ -53,7 +53,7 @@ fun MessageReceiver.handle(message: Message, proto: SignalServiceProtos.Content, } private fun MessageReceiver.handleReadReceipt(message: ReadReceipt) { - val context = MessagingConfiguration.shared.context + val context = MessagingModuleConfiguration.shared.context SSKEnvironment.shared.readReceiptManager.processReadReceipts(context, message.sender!!, message.timestamps!!, message.receivedTimestamp!!) } @@ -65,23 +65,23 @@ private fun MessageReceiver.handleTypingIndicator(message: TypingIndicator) { } fun MessageReceiver.showTypingIndicatorIfNeeded(senderPublicKey: String) { - val context = MessagingConfiguration.shared.context + val context = MessagingModuleConfiguration.shared.context val address = Address.fromSerialized(senderPublicKey) - val threadID = MessagingConfiguration.shared.storage.getThreadIdFor(address) ?: return + val threadID = MessagingModuleConfiguration.shared.storage.getThreadIdFor(address) ?: return SSKEnvironment.shared.typingIndicators.didReceiveTypingStartedMessage(context, threadID, address, 1) } fun MessageReceiver.hideTypingIndicatorIfNeeded(senderPublicKey: String) { - val context = MessagingConfiguration.shared.context + val context = MessagingModuleConfiguration.shared.context val address = Address.fromSerialized(senderPublicKey) - val threadID = MessagingConfiguration.shared.storage.getThreadIdFor(address) ?: return + val threadID = MessagingModuleConfiguration.shared.storage.getThreadIdFor(address) ?: return SSKEnvironment.shared.typingIndicators.didReceiveTypingStoppedMessage(context, threadID, address, 1, false) } fun MessageReceiver.cancelTypingIndicatorsIfNeeded(senderPublicKey: String) { - val context = MessagingConfiguration.shared.context + val context = MessagingModuleConfiguration.shared.context val address = Address.fromSerialized(senderPublicKey) - val threadID = MessagingConfiguration.shared.storage.getThreadIdFor(address) ?: return + val threadID = MessagingModuleConfiguration.shared.storage.getThreadIdFor(address) ?: return SSKEnvironment.shared.typingIndicators.didReceiveIncomingMessage(context, threadID, address, 1) } @@ -99,7 +99,7 @@ private fun MessageReceiver.handleDataExtractionNotification(message: DataExtrac // we don't handle data extraction messages for groups (they shouldn't be sent, but in case we filter them here too) if (message.groupPublicKey != null) return - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage val senderPublicKey = message.sender!! val notification: DataExtractionNotificationInfoMessage = when(message.kind) { is DataExtractionNotification.Kind.Screenshot -> DataExtractionNotificationInfoMessage(DataExtractionNotificationInfoMessage.Kind.SCREENSHOT) @@ -112,8 +112,8 @@ private fun MessageReceiver.handleDataExtractionNotification(message: DataExtrac // Configuration message handling private fun MessageReceiver.handleConfigurationMessage(message: ConfigurationMessage) { - val context = MessagingConfiguration.shared.context - val storage = MessagingConfiguration.shared.storage + val context = MessagingModuleConfiguration.shared.context + val storage = MessagingModuleConfiguration.shared.storage if (TextSecurePreferences.getConfigurationMessageSynced(context) && !TextSecurePreferences.shouldUpdateProfile(context, message.sentTimestamp!!)) return val userPublicKey = storage.getUserPublicKey() if (userPublicKey == null || message.sender != storage.getUserPublicKey()) return @@ -146,8 +146,8 @@ private fun MessageReceiver.handleConfigurationMessage(message: ConfigurationMes } fun MessageReceiver.handleVisibleMessage(message: VisibleMessage, proto: SignalServiceProtos.Content, openGroupID: String?) { - val storage = MessagingConfiguration.shared.storage - val context = MessagingConfiguration.shared.context + val storage = MessagingModuleConfiguration.shared.storage + val context = MessagingModuleConfiguration.shared.context // Update profile if needed val newProfile = message.profile if (newProfile != null) { @@ -180,10 +180,10 @@ fun MessageReceiver.handleVisibleMessage(message: VisibleMessage, proto: SignalS if (message.quote != null && proto.dataMessage.hasQuote()) { val quote = proto.dataMessage.quote val author = Address.fromSerialized(quote.author) - val messageInfo = MessagingConfiguration.shared.messageDataProvider.getMessageForQuote(quote.id, author) + val messageInfo = MessagingModuleConfiguration.shared.messageDataProvider.getMessageForQuote(quote.id, author) if (messageInfo != null) { - val attachments = if (messageInfo.second) MessagingConfiguration.shared.messageDataProvider.getAttachmentsAndLinkPreviewFor(messageInfo.first) else ArrayList() - quoteModel = QuoteModel(quote.id, author, MessagingConfiguration.shared.messageDataProvider.getMessageBodyFor(quote.id, quote.author), false, attachments) + val attachments = if (messageInfo.second) MessagingModuleConfiguration.shared.messageDataProvider.getAttachmentsAndLinkPreviewFor(messageInfo.first) else ArrayList() + quoteModel = QuoteModel(quote.id, author, MessagingModuleConfiguration.shared.messageDataProvider.getMessageBodyFor(quote.id, quote.author), false, attachments) } else { quoteModel = QuoteModel(quote.id, author, quote.text, true, PointerAttachment.forPointers(proto.dataMessage.quote.attachmentsList)) } @@ -251,8 +251,8 @@ private fun MessageReceiver.handleNewClosedGroup(message: ClosedGroupControlMess // Parameter @sender:String is just for inserting incoming info message private fun handleNewClosedGroup(sender: String, sentTimestamp: Long, groupPublicKey: String, name: String, encryptionKeyPair: ECKeyPair, members: List, admins: List, formationTimestamp: Long) { - val context = MessagingConfiguration.shared.context - val storage = MessagingConfiguration.shared.storage + val context = MessagingModuleConfiguration.shared.context + val storage = MessagingModuleConfiguration.shared.storage // Create the group val groupID = GroupUtil.doubleEncodeGroupID(groupPublicKey) if (storage.getGroup(groupID) != null) { @@ -283,7 +283,7 @@ private fun handleNewClosedGroup(sender: String, sentTimestamp: Long, groupPubli private fun MessageReceiver.handleClosedGroupEncryptionKeyPair(message: ClosedGroupControlMessage) { // Prepare - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage val senderPublicKey = message.sender ?: return val kind = message.kind!! as? ClosedGroupControlMessage.Kind.EncryptionKeyPair ?: return val groupPublicKey = kind.publicKey?.toByteArray()?.toHexString() ?: message.groupPublicKey ?: return @@ -321,8 +321,8 @@ private fun MessageReceiver.handleClosedGroupEncryptionKeyPair(message: ClosedGr } private fun MessageReceiver.handleClosedGroupNameChanged(message: ClosedGroupControlMessage) { - val context = MessagingConfiguration.shared.context - val storage = MessagingConfiguration.shared.storage + val context = MessagingModuleConfiguration.shared.context + val storage = MessagingModuleConfiguration.shared.storage val userPublicKey = TextSecurePreferences.getLocalNumber(context) val senderPublicKey = message.sender ?: return val kind = message.kind!! as? ClosedGroupControlMessage.Kind.NameChange ?: return @@ -357,8 +357,8 @@ private fun MessageReceiver.handleClosedGroupNameChanged(message: ClosedGroupCon } private fun MessageReceiver.handleClosedGroupMembersAdded(message: ClosedGroupControlMessage) { - val context = MessagingConfiguration.shared.context - val storage = MessagingConfiguration.shared.storage + val context = MessagingModuleConfiguration.shared.context + val storage = MessagingModuleConfiguration.shared.storage val userPublicKey = storage.getUserPublicKey()!! val senderPublicKey = message.sender ?: return val kind = message.kind!! as? ClosedGroupControlMessage.Kind.MembersAdded ?: return @@ -404,8 +404,8 @@ private fun MessageReceiver.handleClosedGroupMembersAdded(message: ClosedGroupCo } private fun MessageReceiver.handleClosedGroupMembersRemoved(message: ClosedGroupControlMessage) { - val context = MessagingConfiguration.shared.context - val storage = MessagingConfiguration.shared.storage + val context = MessagingModuleConfiguration.shared.context + val storage = MessagingModuleConfiguration.shared.storage val userPublicKey = storage.getUserPublicKey()!! val senderPublicKey = message.sender ?: return val kind = message.kind!! as? ClosedGroupControlMessage.Kind.MembersRemoved ?: return @@ -463,8 +463,8 @@ private fun MessageReceiver.handleClosedGroupMembersRemoved(message: ClosedGroup } private fun MessageReceiver.handleClosedGroupMemberLeft(message: ClosedGroupControlMessage) { - val context = MessagingConfiguration.shared.context - val storage = MessagingConfiguration.shared.storage + val context = MessagingModuleConfiguration.shared.context + val storage = MessagingModuleConfiguration.shared.storage val senderPublicKey = message.sender ?: return val userPublicKey = storage.getUserPublicKey()!! if (message.kind!! !is ClosedGroupControlMessage.Kind.MemberLeft) return @@ -528,7 +528,7 @@ private fun isValidGroupUpdate(group: GroupRecord, } fun MessageReceiver.disableLocalGroupAndUnsubscribe(groupPublicKey: String, groupID: String, userPublicKey: String) { - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage storage.removeClosedGroupPublicKey(groupPublicKey) // Remove the key pairs storage.removeAllClosedGroupEncryptionKeyPairs(groupPublicKey) diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt index 3847e70659..20f860c18c 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt @@ -2,7 +2,7 @@ package org.session.libsession.messaging.sending_receiving import nl.komponents.kovenant.Promise import nl.komponents.kovenant.deferred -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.messaging.jobs.MessageSendJob import org.session.libsession.messaging.jobs.NotifyPNServerJob @@ -12,8 +12,8 @@ import org.session.libsession.messaging.messages.control.ClosedGroupControlMessa import org.session.libsession.messaging.messages.control.ConfigurationMessage import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate import org.session.libsession.messaging.messages.visible.* -import org.session.libsession.messaging.opengroups.OpenGroupAPI -import org.session.libsession.messaging.opengroups.OpenGroupMessage +import org.session.libsession.messaging.open_groups.OpenGroupAPI +import org.session.libsession.messaging.open_groups.OpenGroupMessage import org.session.libsession.messaging.threads.Address import org.session.libsession.messaging.utilities.MessageWrapper import org.session.libsession.snode.RawResponsePromise @@ -72,7 +72,7 @@ object MessageSender { private fun sendToSnodeDestination(destination: Destination, message: Message, isSyncMessage: Boolean = false): Promise { val deferred = deferred() val promise = deferred.promise - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage val userPublicKey = storage.getUserPublicKey() // Set the timestamp, sender and recipient message.sentTimestamp ?: run { message.sentTimestamp = System.currentTimeMillis() } /* Visible messages will already have their sent timestamp set */ @@ -125,7 +125,7 @@ object MessageSender { when (destination) { is Destination.Contact -> ciphertext = MessageSenderEncryption.encryptWithSessionProtocol(plaintext, destination.publicKey) is Destination.ClosedGroup -> { - val encryptionKeyPair = MessagingConfiguration.shared.storage.getLatestClosedGroupEncryptionKeyPair(destination.groupPublicKey)!! + val encryptionKeyPair = MessagingModuleConfiguration.shared.storage.getLatestClosedGroupEncryptionKeyPair(destination.groupPublicKey)!! ciphertext = MessageSenderEncryption.encryptWithSessionProtocol(plaintext, encryptionKeyPair.hexEncodedPublicKey) } is Destination.OpenGroup -> throw Error.PreconditionFailure("Destination should not be open groups!") @@ -195,7 +195,7 @@ object MessageSender { // Open Groups private fun sendToOpenGroupDestination(destination: Destination, message: Message): Promise { val deferred = deferred() - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage message.sentTimestamp ?: run { message.sentTimestamp = System.currentTimeMillis() } message.sender = storage.getUserPublicKey() // Set the failure handler (need it here already for precondition failure handling) @@ -239,7 +239,7 @@ object MessageSender { // Result Handling fun handleSuccessfulMessageSend(message: Message, destination: Destination, isSyncMessage: Boolean = false) { - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage val userPublicKey = storage.getUserPublicKey()!! val messageId = storage.getMessageIdInDatabase(message.sentTimestamp!!, message.sender?:userPublicKey) ?: return // Ignore future self-sends @@ -267,7 +267,7 @@ object MessageSender { } fun handleFailedMessageSend(message: Message, error: Exception) { - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage val userPublicKey = storage.getUserPublicKey()!! storage.setErrorMessage(message.sentTimestamp!!, message.sender?:userPublicKey, error) } @@ -275,7 +275,7 @@ object MessageSender { // Convenience @JvmStatic fun send(message: VisibleMessage, address: Address, attachments: List, quote: SignalQuote?, linkPreview: SignalLinkPreview?) { - val dataProvider = MessagingConfiguration.shared.messageDataProvider + val dataProvider = MessagingModuleConfiguration.shared.messageDataProvider val attachmentIDs = dataProvider.getAttachmentIDsFor(message.id!!) message.attachmentIDs.addAll(attachmentIDs) message.quote = Quote.from(quote) @@ -293,7 +293,7 @@ object MessageSender { @JvmStatic fun send(message: Message, address: Address) { - val threadID = MessagingConfiguration.shared.storage.getOrCreateThreadIdFor(address) + val threadID = MessagingModuleConfiguration.shared.storage.getOrCreateThreadIdFor(address) message.threadID = threadID val destination = Destination.from(address) val job = MessageSendJob(message, destination) @@ -301,13 +301,13 @@ object MessageSender { } fun sendNonDurably(message: VisibleMessage, attachments: List, address: Address): Promise { - val attachmentIDs = MessagingConfiguration.shared.messageDataProvider.getAttachmentIDsFor(message.id!!) + val attachmentIDs = MessagingModuleConfiguration.shared.messageDataProvider.getAttachmentIDsFor(message.id!!) message.attachmentIDs.addAll(attachmentIDs) return sendNonDurably(message, address) } fun sendNonDurably(message: Message, address: Address): Promise { - val threadID = MessagingConfiguration.shared.storage.getOrCreateThreadIdFor(address) + val threadID = MessagingModuleConfiguration.shared.storage.getOrCreateThreadIdFor(address) message.threadID = threadID val destination = Destination.from(address) return send(message, destination) diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroup.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroup.kt index bcd824f3a5..427bf4b832 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroup.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroup.kt @@ -5,7 +5,7 @@ package org.session.libsession.messaging.sending_receiving import com.google.protobuf.ByteString import nl.komponents.kovenant.Promise import nl.komponents.kovenant.deferred -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.messages.control.ClosedGroupControlMessage import org.session.libsession.messaging.sending_receiving.MessageSender.Error import org.session.libsession.messaging.sending_receiving.notifications.PushNotificationAPI @@ -32,8 +32,8 @@ fun MessageSender.create(name: String, members: Collection): Promise() ThreadUtils.queue { // Prepare - val context = MessagingConfiguration.shared.context - val storage = MessagingConfiguration.shared.storage + val context = MessagingModuleConfiguration.shared.context + val storage = MessagingModuleConfiguration.shared.storage val userPublicKey = storage.getUserPublicKey()!! val membersAsData = members.map { ByteString.copyFrom(Hex.fromStringCondensed(it)) } // Generate the group's public key @@ -72,8 +72,8 @@ fun MessageSender.create(name: String, members: Collection): Promise, name: String) { - val context = MessagingConfiguration.shared.context - val storage = MessagingConfiguration.shared.storage + val context = MessagingModuleConfiguration.shared.context + val storage = MessagingModuleConfiguration.shared.storage val groupID = GroupUtil.doubleEncodeGroupID(groupPublicKey) val group = storage.getGroup(groupID) ?: run { Log.d("Loki", "Can't update nonexistent closed group.") @@ -90,8 +90,8 @@ fun MessageSender.update(groupPublicKey: String, members: List, name: St } fun MessageSender.setName(groupPublicKey: String, newName: String) { - val context = MessagingConfiguration.shared.context - val storage = MessagingConfiguration.shared.storage + val context = MessagingModuleConfiguration.shared.context + val storage = MessagingModuleConfiguration.shared.storage val groupID = GroupUtil.doubleEncodeGroupID(groupPublicKey) val group = storage.getGroup(groupID) ?: run { Log.d("Loki", "Can't change name for nonexistent closed group.") @@ -114,8 +114,8 @@ fun MessageSender.setName(groupPublicKey: String, newName: String) { } fun MessageSender.addMembers(groupPublicKey: String, membersToAdd: List) { - val context = MessagingConfiguration.shared.context - val storage = MessagingConfiguration.shared.storage + val context = MessagingModuleConfiguration.shared.context + val storage = MessagingModuleConfiguration.shared.storage val groupID = GroupUtil.doubleEncodeGroupID(groupPublicKey) val group = storage.getGroup(groupID) ?: run { Log.d("Loki", "Can't add members to nonexistent closed group.") @@ -157,8 +157,8 @@ fun MessageSender.addMembers(groupPublicKey: String, membersToAdd: List) } fun MessageSender.removeMembers(groupPublicKey: String, membersToRemove: List) { - val context = MessagingConfiguration.shared.context - val storage = MessagingConfiguration.shared.storage + val context = MessagingModuleConfiguration.shared.context + val storage = MessagingModuleConfiguration.shared.storage val userPublicKey = storage.getUserPublicKey()!! val groupID = GroupUtil.doubleEncodeGroupID(groupPublicKey) val group = storage.getGroup(groupID) ?: run { @@ -198,8 +198,8 @@ fun MessageSender.removeMembers(groupPublicKey: String, membersToRemove: List { val deferred = deferred() ThreadUtils.queue { - val context = MessagingConfiguration.shared.context - val storage = MessagingConfiguration.shared.storage + val context = MessagingModuleConfiguration.shared.context + val storage = MessagingModuleConfiguration.shared.storage val userPublicKey = TextSecurePreferences.getLocalNumber(context)!! val groupID = GroupUtil.doubleEncodeGroupID(groupPublicKey) val group = storage.getGroup(groupID) ?: return@queue deferred.reject(Error.NoThread) @@ -230,7 +230,7 @@ fun MessageSender.leave(groupPublicKey: String, notifyUser: Boolean = true): Pro fun MessageSender.generateAndSendNewEncryptionKeyPair(groupPublicKey: String, targetMembers: Collection) { // Prepare - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage val userPublicKey = storage.getUserPublicKey()!! val groupID = GroupUtil.doubleEncodeGroupID(groupPublicKey) val group = storage.getGroup(groupID) ?: run { @@ -279,7 +279,7 @@ fun MessageSender.sendEncryptionKeyPair(groupPublicKey: String, newKeyPair: ECKe } fun MessageSender.sendLatestEncryptionKeyPair(publicKey: String, groupPublicKey: String) { - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage val groupID = GroupUtil.doubleEncodeGroupID(groupPublicKey) val group = storage.getGroup(groupID) ?: run { Log.d("Loki", "Can't send encryption key pair for nonexistent closed group.") diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderEncryption.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderEncryption.kt index a108724e9c..c96fc82b16 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderEncryption.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderEncryption.kt @@ -5,7 +5,7 @@ import com.goterl.lazycode.lazysodium.SodiumAndroid import com.goterl.lazycode.lazysodium.interfaces.Box import com.goterl.lazycode.lazysodium.interfaces.Sign -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.sending_receiving.MessageSender.Error import org.session.libsession.utilities.KeyPairUtilities @@ -26,7 +26,7 @@ object MessageSenderEncryption { * @return the encrypted message. */ internal fun encryptWithSessionProtocol(plaintext: ByteArray, recipientHexEncodedX25519PublicKey: String): ByteArray{ - val context = MessagingConfiguration.shared.context + val context = MessagingModuleConfiguration.shared.context val userED25519KeyPair = KeyPairUtilities.getUserED25519KeyPair(context) ?: throw Error.NoUserED25519KeyPair val recipientX25519PublicKey = Hex.fromStringCondensed(recipientHexEncodedX25519PublicKey.removing05PrefixIfNeeded()) diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/attachments/DatabaseAttachment.java b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/attachments/DatabaseAttachment.java index 7253cf31e5..aba155f160 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/attachments/DatabaseAttachment.java +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/attachments/DatabaseAttachment.java @@ -4,7 +4,7 @@ import android.net.Uri; import androidx.annotation.Nullable; -import org.session.libsession.messaging.MessagingConfiguration; +import org.session.libsession.messaging.MessagingModuleConfiguration; public class DatabaseAttachment extends Attachment { @@ -33,7 +33,7 @@ public class DatabaseAttachment extends Attachment { @Nullable public Uri getDataUri() { if (hasData) { - return MessagingConfiguration.shared.getStorage().getAttachmentDataUri(attachmentId); + return MessagingModuleConfiguration.shared.getStorage().getAttachmentDataUri(attachmentId); } else { return null; } @@ -43,7 +43,7 @@ public class DatabaseAttachment extends Attachment { @Nullable public Uri getThumbnailUri() { if (hasThumbnail) { - return MessagingConfiguration.shared.getStorage().getAttachmentThumbnailUri(attachmentId); + return MessagingModuleConfiguration.shared.getStorage().getAttachmentThumbnailUri(attachmentId); } else { return null; } diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/PushNotificationAPI.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/PushNotificationAPI.kt index ed0f771498..76a93ac344 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/PushNotificationAPI.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/notifications/PushNotificationAPI.kt @@ -5,7 +5,7 @@ import nl.komponents.kovenant.functional.map import okhttp3.MediaType import okhttp3.Request import okhttp3.RequestBody -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.snode.OnionRequestAPI import org.session.libsession.utilities.TextSecurePreferences import org.session.libsignal.service.loki.utilities.retryIfNeeded @@ -14,7 +14,7 @@ import org.session.libsignal.utilities.logging.Log @SuppressLint("StaticFieldLeak") object PushNotificationAPI { - val context = MessagingConfiguration.shared.context + val context = MessagingModuleConfiguration.shared.context val server = "https://live.apns.getsession.org" val serverPublicKey = "642a6585919742e5a2d4dc51244964fbcd8bcab2b75612407de58b810740d049" private val maxRetryCount = 4 @@ -50,8 +50,8 @@ object PushNotificationAPI { } } // Unsubscribe from all closed groups - val allClosedGroupPublicKeys = MessagingConfiguration.shared.storage.getAllClosedGroupPublicKeys() - val userPublicKey = MessagingConfiguration.shared.storage.getUserPublicKey()!! + val allClosedGroupPublicKeys = MessagingModuleConfiguration.shared.storage.getAllClosedGroupPublicKeys() + val userPublicKey = MessagingModuleConfiguration.shared.storage.getUserPublicKey()!! allClosedGroupPublicKeys.forEach { closedGroup -> performOperation(ClosedGroupOperation.Unsubscribe, closedGroup, userPublicKey) } @@ -80,7 +80,7 @@ object PushNotificationAPI { } } // Subscribe to all closed groups - val allClosedGroupPublicKeys = MessagingConfiguration.shared.storage.getAllClosedGroupPublicKeys() + val allClosedGroupPublicKeys = MessagingModuleConfiguration.shared.storage.getAllClosedGroupPublicKeys() allClosedGroupPublicKeys.forEach { closedGroup -> performOperation(ClosedGroupOperation.Subscribe, closedGroup, publicKey) } diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/ClosedGroupPoller.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/ClosedGroupPoller.kt index b78c382658..e6d68911d3 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/ClosedGroupPoller.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/ClosedGroupPoller.kt @@ -4,7 +4,7 @@ import android.os.Handler import nl.komponents.kovenant.Promise import nl.komponents.kovenant.functional.bind import nl.komponents.kovenant.functional.map -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.messaging.jobs.MessageReceiveJob import org.session.libsession.messaging.utilities.MessageWrapper @@ -59,7 +59,7 @@ class ClosedGroupPoller { // region Private API private fun poll(): List> { if (!isPolling) { return listOf() } - val publicKeys = MessagingConfiguration.shared.storage.getAllActiveClosedGroupPublicKeys() + val publicKeys = MessagingModuleConfiguration.shared.storage.getAllActiveClosedGroupPublicKeys() return publicKeys.map { publicKey -> val promise = SnodeAPI.getSwarm(publicKey).bind { swarm -> val snode = swarm.getRandomElementOrNull() ?: throw InsufficientSnodesException() // Should be cryptographically secure @@ -67,7 +67,7 @@ class ClosedGroupPoller { SnodeAPI.getRawMessages(snode, publicKey).map {SnodeAPI.parseRawMessagesResponse(it, snode, publicKey) } } promise.successBackground { messages -> - if (!MessagingConfiguration.shared.storage.isGroupActive(publicKey)) { + if (!MessagingModuleConfiguration.shared.storage.isGroupActive(publicKey)) { // ignore inactive group's messages return@successBackground } diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/OpenGroupPoller.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/OpenGroupPoller.kt index d213b3b6a6..b94cb07e21 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/OpenGroupPoller.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/OpenGroupPoller.kt @@ -3,12 +3,12 @@ package org.session.libsession.messaging.sending_receiving.pollers import com.google.protobuf.ByteString import nl.komponents.kovenant.Promise import nl.komponents.kovenant.deferred -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.messaging.jobs.MessageReceiveJob -import org.session.libsession.messaging.opengroups.OpenGroup -import org.session.libsession.messaging.opengroups.OpenGroupAPI -import org.session.libsession.messaging.opengroups.OpenGroupMessage +import org.session.libsession.messaging.open_groups.OpenGroup +import org.session.libsession.messaging.open_groups.OpenGroupAPI +import org.session.libsession.messaging.open_groups.OpenGroupMessage import org.session.libsignal.service.internal.push.SignalServiceProtos.* import org.session.libsignal.utilities.logging.Log import org.session.libsignal.utilities.successBackground @@ -26,7 +26,7 @@ class OpenGroupPoller(private val openGroup: OpenGroup, private val executorServ private val cancellableFutures = mutableListOf>() // region Convenience - private val userHexEncodedPublicKey = MessagingConfiguration.shared.storage.getUserPublicKey() ?: "" + private val userHexEncodedPublicKey = MessagingModuleConfiguration.shared.storage.getUserPublicKey() ?: "" private var displayNameUpdates = setOf() // endregion @@ -79,7 +79,7 @@ class OpenGroupPoller(private val openGroup: OpenGroup, private val executorServ fun generateDisplayName(rawDisplayName: String): String { return "$rawDisplayName (...${senderPublicKey.takeLast(8)})" } - val senderDisplayName = MessagingConfiguration.shared.storage.getOpenGroupDisplayName(senderPublicKey, openGroup.channel, openGroup.server) ?: generateDisplayName(message.displayName) + val senderDisplayName = MessagingModuleConfiguration.shared.storage.getOpenGroupDisplayName(senderPublicKey, openGroup.channel, openGroup.server) ?: generateDisplayName(message.displayName) val id = openGroup.id.toByteArray() // Main message val dataMessageProto = DataMessage.newBuilder() @@ -203,7 +203,7 @@ class OpenGroupPoller(private val openGroup: OpenGroup, private val executorServ for (pair in mapping.entries) { if (pair.key == userHexEncodedPublicKey) continue val senderDisplayName = "${pair.value} (...${pair.key.substring(pair.key.count() - 8)})" - MessagingConfiguration.shared.storage.setOpenGroupDisplayName(pair.key, openGroup.channel, openGroup.server, senderDisplayName) + MessagingModuleConfiguration.shared.storage.setOpenGroupDisplayName(pair.key, openGroup.channel, openGroup.server, senderDisplayName) } }.fail { displayNameUpdates = displayNameUpdates.union(hexEncodedPublicKeys) @@ -212,9 +212,9 @@ class OpenGroupPoller(private val openGroup: OpenGroup, private val executorServ private fun pollForDeletedMessages() { OpenGroupAPI.getDeletedMessageServerIDs(openGroup.channel, openGroup.server).success { deletedMessageServerIDs -> - val deletedMessageIDs = deletedMessageServerIDs.mapNotNull { MessagingConfiguration.shared.messageDataProvider.getMessageID(it) } + val deletedMessageIDs = deletedMessageServerIDs.mapNotNull { MessagingModuleConfiguration.shared.messageDataProvider.getMessageID(it) } deletedMessageIDs.forEach { - MessagingConfiguration.shared.messageDataProvider.deleteMessage(it) + MessagingModuleConfiguration.shared.messageDataProvider.deleteMessage(it) } }.fail { Log.d("Loki", "Failed to get deleted messages for group chat with ID: ${openGroup.channel} on server: ${openGroup.server}.") diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt index 80db18b7e6..d8187bad03 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt @@ -2,7 +2,7 @@ package org.session.libsession.messaging.sending_receiving.pollers import nl.komponents.kovenant.* import nl.komponents.kovenant.functional.bind -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.messaging.jobs.MessageReceiveJob import org.session.libsession.messaging.utilities.MessageWrapper @@ -17,7 +17,7 @@ import java.util.* private class PromiseCanceledException : Exception("Promise canceled.") class Poller { - var userPublicKey = MessagingConfiguration.shared.storage.getUserPublicKey() ?: "" + var userPublicKey = MessagingModuleConfiguration.shared.storage.getUserPublicKey() ?: "" private var hasStarted: Boolean = false private val usedSnodes: MutableSet = mutableSetOf() public var isCaughtUp = false diff --git a/libsession/src/main/java/org/session/libsession/messaging/threads/GroupRecord.kt b/libsession/src/main/java/org/session/libsession/messaging/threads/GroupRecord.kt index 5e09d30ee5..ac12a60e72 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/threads/GroupRecord.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/threads/GroupRecord.kt @@ -13,6 +13,7 @@ class GroupRecord( ) { var members: List
= LinkedList
() var admins: List
= LinkedList
() + fun getId(): ByteArray { return try { GroupUtil.getDecodedGroupIDAsData(encodedId) diff --git a/libsession/src/main/java/org/session/libsession/messaging/threads/recipients/Recipient.java b/libsession/src/main/java/org/session/libsession/messaging/threads/recipients/Recipient.java index 1c9463ec38..9a85c75c7c 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/threads/recipients/Recipient.java +++ b/libsession/src/main/java/org/session/libsession/messaging/threads/recipients/Recipient.java @@ -28,7 +28,7 @@ import androidx.annotation.Nullable; import com.annimon.stream.function.Consumer; import org.greenrobot.eventbus.EventBus; -import org.session.libsession.messaging.MessagingConfiguration; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.messaging.avatars.TransparentContactPhoto; import org.session.libsession.messaging.threads.Address; import org.session.libsession.messaging.threads.GroupRecord; @@ -286,7 +286,7 @@ public class Recipient implements RecipientModifiedListener { } public synchronized @Nullable String getName() { - String displayName = MessagingConfiguration.shared.getStorage().getDisplayName(this.address.toString()); + String displayName = MessagingModuleConfiguration.shared.getStorage().getDisplayName(this.address.toString()); if (displayName != null) { return displayName; } if (this.name == null && isMmsGroupRecipient()) { diff --git a/libsession/src/main/java/org/session/libsession/messaging/threads/recipients/RecipientProvider.java b/libsession/src/main/java/org/session/libsession/messaging/threads/recipients/RecipientProvider.java index e42363acd1..2e634aa957 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/threads/recipients/RecipientProvider.java +++ b/libsession/src/main/java/org/session/libsession/messaging/threads/recipients/RecipientProvider.java @@ -23,7 +23,7 @@ import android.text.TextUtils; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.session.libsession.messaging.MessagingConfiguration; +import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsignal.libsignal.util.guava.Optional; import org.session.libsession.utilities.color.MaterialColor; import org.session.libsession.messaging.threads.Address; @@ -115,7 +115,7 @@ class RecipientProvider { private @NonNull RecipientDetails getIndividualRecipientDetails(Context context, @NonNull Address address, Optional settings) { if (!settings.isPresent()) { - settings = Optional.fromNullable(MessagingConfiguration.shared.getStorage().getRecipientSettings(address)); + settings = Optional.fromNullable(MessagingModuleConfiguration.shared.getStorage().getRecipientSettings(address)); } if (!settings.isPresent() && STATIC_DETAILS.containsKey(address.serialize())) { @@ -130,12 +130,12 @@ class RecipientProvider { private @NonNull RecipientDetails getGroupRecipientDetails(Context context, Address groupId, Optional groupRecord, Optional settings, boolean asynchronous) { if (!groupRecord.isPresent()) { - groupRecord = Optional.fromNullable(MessagingConfiguration.shared.getStorage().getGroup(groupId.toGroupString())); + groupRecord = Optional.fromNullable(MessagingModuleConfiguration.shared.getStorage().getGroup(groupId.toGroupString())); } if (!settings.isPresent()) { - settings = Optional.fromNullable(MessagingConfiguration.shared.getStorage().getRecipientSettings(groupId)); + settings = Optional.fromNullable(MessagingModuleConfiguration.shared.getStorage().getRecipientSettings(groupId)); } if (groupRecord.isPresent()) { diff --git a/libsession/src/main/java/org/session/libsession/messaging/utilities/UpdateMessageBuilder.kt b/libsession/src/main/java/org/session/libsession/messaging/utilities/ClosedGroupUpdateMessageBuilder.kt similarity index 80% rename from libsession/src/main/java/org/session/libsession/messaging/utilities/UpdateMessageBuilder.kt rename to libsession/src/main/java/org/session/libsession/messaging/utilities/ClosedGroupUpdateMessageBuilder.kt index 4239c8bdb2..3393d50b99 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/utilities/UpdateMessageBuilder.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/utilities/ClosedGroupUpdateMessageBuilder.kt @@ -2,39 +2,38 @@ package org.session.libsession.messaging.utilities import android.content.Context import org.session.libsession.R -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage import org.session.libsession.utilities.ExpirationUtil -import org.session.libsignal.service.api.messages.SignalServiceGroup -object UpdateMessageBuilder { +object ClosedGroupUpdateMessageBuilder { - fun buildGroupUpdateMessage(context: Context, updateMessageData: UpdateMessageData, sender: String? = null, isOutgoing: Boolean = false): String { + fun buildGroupUpdateMessage(context: Context, updateMessageData: ClosedGroupUpdateMessageData, sender: String? = null, isOutgoing: Boolean = false): String { var message = "" val updateData = updateMessageData.kind ?: return message if (!isOutgoing && sender == null) return message val senderName: String = if (!isOutgoing) { - MessagingConfiguration.shared.storage.getDisplayNameForRecipient(sender!!) ?: sender + MessagingModuleConfiguration.shared.storage.getDisplayNameForRecipient(sender!!) ?: sender } else { context.getString(R.string.MessageRecord_you) } when (updateData) { - is UpdateMessageData.Kind.GroupCreation -> { + is ClosedGroupUpdateMessageData.Kind.GroupCreation -> { message = if (isOutgoing) { context.getString(R.string.MessageRecord_you_created_a_new_group) } else { context.getString(R.string.MessageRecord_s_added_you_to_the_group, senderName) } } - is UpdateMessageData.Kind.GroupNameChange -> { + is ClosedGroupUpdateMessageData.Kind.GroupNameChange -> { message = if (isOutgoing) { context.getString(R.string.MessageRecord_you_renamed_the_group_to_s, updateData.name) } else { context.getString(R.string.MessageRecord_s_renamed_the_group_to_s, senderName, updateData.name) } } - is UpdateMessageData.Kind.GroupMemberAdded -> { + is ClosedGroupUpdateMessageData.Kind.GroupMemberAdded -> { val members = updateData.updatedMembers.joinToString(", ") { - MessagingConfiguration.shared.storage.getDisplayNameForRecipient(it) ?: it + MessagingModuleConfiguration.shared.storage.getDisplayNameForRecipient(it) ?: it } message = if (isOutgoing) { context.getString(R.string.MessageRecord_you_added_s_to_the_group, members) @@ -42,8 +41,8 @@ object UpdateMessageBuilder { context.getString(R.string.MessageRecord_s_added_s_to_the_group, senderName, members) } } - is UpdateMessageData.Kind.GroupMemberRemoved -> { - val storage = MessagingConfiguration.shared.storage + is ClosedGroupUpdateMessageData.Kind.GroupMemberRemoved -> { + val storage = MessagingModuleConfiguration.shared.storage val userPublicKey = storage.getUserPublicKey()!! // 1st case: you are part of the removed members message = if (userPublicKey in updateData.updatedMembers) { @@ -64,7 +63,7 @@ object UpdateMessageBuilder { } } } - is UpdateMessageData.Kind.GroupMemberLeft -> { + is ClosedGroupUpdateMessageData.Kind.GroupMemberLeft -> { message = if (isOutgoing) { context.getString(R.string.MessageRecord_left_group) } else { @@ -78,7 +77,7 @@ object UpdateMessageBuilder { fun buildExpirationTimerMessage(context: Context, duration: Long, sender: String? = null, isOutgoing: Boolean = false): String { if (!isOutgoing && sender == null) return "" val senderName: String? = if (!isOutgoing) { - MessagingConfiguration.shared.storage.getDisplayNameForRecipient(sender!!) ?: sender + MessagingModuleConfiguration.shared.storage.getDisplayNameForRecipient(sender!!) ?: sender } else { context.getString(R.string.MessageRecord_you) } return if (duration <= 0) { if (isOutgoing) context.getString(R.string.MessageRecord_you_disabled_disappearing_messages) @@ -91,7 +90,7 @@ object UpdateMessageBuilder { } fun buildDataExtractionMessage(context: Context, kind: DataExtractionNotificationInfoMessage.Kind, sender: String? = null): String { - val senderName = MessagingConfiguration.shared.storage.getDisplayNameForRecipient(sender!!) ?: sender + val senderName = MessagingModuleConfiguration.shared.storage.getDisplayNameForRecipient(sender!!) ?: sender return when (kind) { DataExtractionNotificationInfoMessage.Kind.SCREENSHOT -> context.getString(R.string.MessageRecord_s_took_a_screenshot, senderName) diff --git a/libsession/src/main/java/org/session/libsession/messaging/utilities/UpdateMessageData.kt b/libsession/src/main/java/org/session/libsession/messaging/utilities/ClosedGroupUpdateMessageData.kt similarity index 70% rename from libsession/src/main/java/org/session/libsession/messaging/utilities/UpdateMessageData.kt rename to libsession/src/main/java/org/session/libsession/messaging/utilities/ClosedGroupUpdateMessageData.kt index 4285bab78e..47efd03a4c 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/utilities/UpdateMessageData.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/utilities/ClosedGroupUpdateMessageData.kt @@ -9,7 +9,7 @@ import org.session.libsignal.utilities.logging.Log import java.util.* // class used to save update messages details -class UpdateMessageData () { +class ClosedGroupUpdateMessageData () { var kind: Kind? = null @@ -41,22 +41,22 @@ class UpdateMessageData () { } companion object { - val TAG = UpdateMessageData::class.simpleName + val TAG = ClosedGroupUpdateMessageData::class.simpleName - fun buildGroupUpdate(type: SignalServiceGroup.Type, name: String, members: Collection): UpdateMessageData? { + fun buildGroupUpdate(type: SignalServiceGroup.Type, name: String, members: Collection): ClosedGroupUpdateMessageData? { return when(type) { - SignalServiceGroup.Type.CREATION -> UpdateMessageData(Kind.GroupCreation()) - SignalServiceGroup.Type.NAME_CHANGE -> UpdateMessageData(Kind.GroupNameChange(name)) - SignalServiceGroup.Type.MEMBER_ADDED -> UpdateMessageData(Kind.GroupMemberAdded(members)) - SignalServiceGroup.Type.MEMBER_REMOVED -> UpdateMessageData(Kind.GroupMemberRemoved(members)) - SignalServiceGroup.Type.QUIT -> UpdateMessageData(Kind.GroupMemberLeft()) + SignalServiceGroup.Type.CREATION -> ClosedGroupUpdateMessageData(Kind.GroupCreation()) + SignalServiceGroup.Type.NAME_CHANGE -> ClosedGroupUpdateMessageData(Kind.GroupNameChange(name)) + SignalServiceGroup.Type.MEMBER_ADDED -> ClosedGroupUpdateMessageData(Kind.GroupMemberAdded(members)) + SignalServiceGroup.Type.MEMBER_REMOVED -> ClosedGroupUpdateMessageData(Kind.GroupMemberRemoved(members)) + SignalServiceGroup.Type.QUIT -> ClosedGroupUpdateMessageData(Kind.GroupMemberLeft()) else -> null } } - fun fromJSON(json: String): UpdateMessageData? { + fun fromJSON(json: String): ClosedGroupUpdateMessageData? { return try { - JsonUtil.fromJson(json, UpdateMessageData::class.java) + JsonUtil.fromJson(json, ClosedGroupUpdateMessageData::class.java) } catch (e: JsonParseException) { Log.e(TAG, "${e.message}") null diff --git a/libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt b/libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt index d18527bfe5..562715a90a 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/utilities/DotNetAPI.kt @@ -6,10 +6,9 @@ import nl.komponents.kovenant.functional.map import nl.komponents.kovenant.then import okhttp3.* -import org.session.libsession.messaging.MessagingConfiguration +import org.session.libsession.messaging.MessagingModuleConfiguration import org.session.libsession.snode.OnionRequestAPI -import org.session.libsession.snode.SnodeAPI -import org.session.libsession.messaging.fileserver.FileServerAPI +import org.session.libsession.messaging.file_server.FileServerAPI import org.session.libsignal.utilities.logging.Log import org.session.libsignal.utilities.DiffieHellman @@ -62,7 +61,7 @@ open class DotNetAPI { public data class UploadResult(val id: Long, val url: String, val digest: ByteArray?) fun getAuthToken(server: String): Promise { - val storage = MessagingConfiguration.shared.storage + val storage = MessagingModuleConfiguration.shared.storage val token = storage.getAuthToken(server) if (token != null) { return Promise.of(token) } // Avoid multiple token requests to the server by caching @@ -81,7 +80,7 @@ open class DotNetAPI { private fun requestNewAuthToken(server: String): Promise { Log.d("Loki", "Requesting auth token for server: $server.") - val userKeyPair = MessagingConfiguration.shared.storage.getUserKeyPair() ?: throw Error.Generic + val userKeyPair = MessagingModuleConfiguration.shared.storage.getUserKeyPair() ?: throw Error.Generic val parameters: Map = mapOf( "pubKey" to userKeyPair.first ) return execute(HTTPVerb.GET, server, "loki/v1/get_challenge", false, parameters).map { json -> try { @@ -107,7 +106,7 @@ open class DotNetAPI { private fun submitAuthToken(token: String, server: String): Promise { Log.d("Loki", "Submitting auth token for server: $server.") - val userPublicKey = MessagingConfiguration.shared.storage.getUserPublicKey() ?: throw Error.Generic + val userPublicKey = MessagingModuleConfiguration.shared.storage.getUserPublicKey() ?: throw Error.Generic val parameters = mapOf( "pubKey" to userPublicKey, "token" to token ) return execute(HTTPVerb.POST, server, "loki/v1/submit_challenge", false, parameters, isJSONRequired = false).map { token } } @@ -146,7 +145,7 @@ open class DotNetAPI { if (exception is HTTP.HTTPRequestFailedException) { val statusCode = exception.statusCode if (statusCode == 401 || statusCode == 403) { - MessagingConfiguration.shared.storage.setAuthToken(server, null) + MessagingModuleConfiguration.shared.storage.setAuthToken(server, null) throw Error.TokenExpired } } @@ -335,7 +334,7 @@ open class DotNetAPI { if (exception is HTTP.HTTPRequestFailedException) { val statusCode = exception.statusCode if (statusCode == 401 || statusCode == 403) { - MessagingConfiguration.shared.storage.setAuthToken(server, null) + MessagingModuleConfiguration.shared.storage.setAuthToken(server, null) } throw NonSuccessfulResponseCodeException("Request returned with status code ${exception.statusCode}.") } diff --git a/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt b/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt index 2cf6b18e6a..4447c494e5 100644 --- a/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt +++ b/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt @@ -6,7 +6,7 @@ import nl.komponents.kovenant.deferred import nl.komponents.kovenant.functional.bind import nl.komponents.kovenant.functional.map import okhttp3.Request -import org.session.libsession.messaging.fileserver.FileServerAPI +import org.session.libsession.messaging.file_server.FileServerAPI import org.session.libsession.utilities.AESGCM import org.session.libsignal.utilities.logging.Log import org.session.libsignal.utilities.Base64 From 69f05dabdfab610eb613ed1c1b0b70dff2439cee Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Mon, 26 Apr 2021 11:23:09 +1000 Subject: [PATCH 07/13] Clean --- .../securesms/BindableConversationItem.java | 2 +- .../securesms/components/InputPanel.java | 2 +- .../securesms/components/LinkPreviewView.java | 2 +- .../conversation/ConversationActivity.java | 2 +- .../conversation/ConversationFragment.java | 2 +- .../securesms/conversation/ConversationItem.java | 2 +- .../conversation/ConversationUpdateItem.java | 2 +- .../securesms/database/MmsDatabase.java | 3 +-- .../thoughtcrime/securesms/database/Storage.kt | 4 ++-- .../database/model/MediaMmsMessageRecord.java | 2 +- .../securesms/database/model/MessageRecord.java | 2 +- .../database/model/MmsMessageRecord.java | 2 +- .../linkpreview/LinkPreviewRepository.java | 2 +- .../linkpreview/LinkPreviewViewModel.java | 3 +-- .../loki/protocol/ClosedGroupsProtocolV2.kt | 3 +-- .../libsession/messaging/StorageProtocol.kt | 4 ++-- .../messages/signal/IncomingMediaMessage.java | 4 ++-- .../signal/OutgoingGroupMediaMessage.java | 6 +----- .../messages/signal/OutgoingMediaMessage.java | 2 +- .../signal/OutgoingSecureMediaMessage.java | 2 +- .../messaging/messages/visible/LinkPreview.kt | 2 +- .../sending_receiving/MessageReceiver.kt | 16 ++++++++-------- .../messaging/sending_receiving/MessageSender.kt | 2 +- ...oup.kt => MessageSenderClosedGroupHandler.kt} | 0 ...eiverHandler.kt => ReceivedMessageHandler.kt} | 4 ++-- .../DataExtractionNotificationInfoMessage.kt | 2 +- .../LinkPreview.java | 2 +- .../sending_receiving/pollers/OpenGroupPoller.kt | 14 +++++++------- .../sending_receiving/quotes/QuoteModel.kt | 9 ++++----- .../utilities/ClosedGroupUpdateMessageBuilder.kt | 2 +- 30 files changed, 49 insertions(+), 57 deletions(-) rename libsession/src/main/java/org/session/libsession/messaging/sending_receiving/{MessageSenderClosedGroup.kt => MessageSenderClosedGroupHandler.kt} (100%) rename libsession/src/main/java/org/session/libsession/messaging/sending_receiving/{MessageReceiverHandler.kt => ReceivedMessageHandler.kt} (99%) rename libsession/src/main/java/org/session/libsession/messaging/sending_receiving/{dataextraction => data_extraction}/DataExtractionNotificationInfoMessage.kt (73%) rename libsession/src/main/java/org/session/libsession/messaging/sending_receiving/{linkpreview => link_preview}/LinkPreview.java (96%) diff --git a/app/src/main/java/org/thoughtcrime/securesms/BindableConversationItem.java b/app/src/main/java/org/thoughtcrime/securesms/BindableConversationItem.java index 95cef276dd..5772505950 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/BindableConversationItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/BindableConversationItem.java @@ -9,7 +9,7 @@ import org.thoughtcrime.securesms.database.model.MmsMessageRecord; import org.thoughtcrime.securesms.mms.GlideRequests; import org.session.libsignal.libsignal.util.guava.Optional; -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview; import org.session.libsession.messaging.threads.Address; import org.session.libsession.messaging.threads.recipients.Recipient; diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/InputPanel.java b/app/src/main/java/org/thoughtcrime/securesms/components/InputPanel.java index 8fb1f9656b..5a67ee67ab 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/InputPanel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/InputPanel.java @@ -30,7 +30,7 @@ import org.thoughtcrime.securesms.loki.utilities.MentionUtilities; import org.thoughtcrime.securesms.mms.GlideRequests; import org.thoughtcrime.securesms.mms.SlideDeck; -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview; import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel; import org.session.libsession.messaging.threads.recipients.Recipient; import org.session.libsession.utilities.TextSecurePreferences; diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/LinkPreviewView.java b/app/src/main/java/org/thoughtcrime/securesms/components/LinkPreviewView.java index 64dd061206..5b2199896a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/LinkPreviewView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/LinkPreviewView.java @@ -17,7 +17,7 @@ import org.thoughtcrime.securesms.mms.GlideRequests; import org.thoughtcrime.securesms.mms.ImageSlide; import org.thoughtcrime.securesms.mms.SlidesClickedListener; -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview; import network.loki.messenger.R; import okhttp3.HttpUrl; diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java index 1582f36227..ecc449b4f3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -183,7 +183,7 @@ import org.session.libsession.utilities.ServiceUtil; import org.session.libsession.utilities.Util; import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact; -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview; import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel; import org.session.libsession.messaging.threads.GroupRecord; import org.session.libsession.utilities.ExpirationUtil; diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java index b487f52716..42f8e03d5a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java @@ -88,7 +88,7 @@ import org.thoughtcrime.securesms.permissions.Permissions; import org.session.libsession.messaging.threads.recipients.Recipient; import org.session.libsession.messaging.sending_receiving.MessageSender; import org.session.libsession.messaging.messages.signal.OutgoingTextMessage; -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview; import org.thoughtcrime.securesms.util.CommunicationActions; import org.thoughtcrime.securesms.util.SaveAttachmentTask; import org.thoughtcrime.securesms.util.StickyHeaderDecoration; diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java index 314b5e723c..6950fb5af1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java @@ -57,7 +57,7 @@ import org.session.libsession.messaging.jobs.JobQueue; import org.session.libsession.messaging.open_groups.OpenGroupAPI; import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress; import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment; -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview; import org.session.libsession.messaging.threads.recipients.Recipient; import org.session.libsession.messaging.threads.recipients.RecipientModifiedListener; import org.session.libsession.utilities.GroupUtil; diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationUpdateItem.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationUpdateItem.java index 91d1c4244b..05fb371bf5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationUpdateItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationUpdateItem.java @@ -14,7 +14,7 @@ import androidx.annotation.ColorInt; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage; +import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage; import org.thoughtcrime.securesms.BindableConversationItem; import org.thoughtcrime.securesms.database.model.MessageRecord; import org.thoughtcrime.securesms.loki.utilities.GeneralUtilitiesKt; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java index fd3c793d1f..84ad24c601 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/MmsDatabase.java @@ -28,7 +28,6 @@ import com.annimon.stream.Collectors; import com.annimon.stream.Stream; import com.google.android.mms.pdu_alt.NotificationInd; import com.google.android.mms.pdu_alt.PduHeaders; -import com.google.protobuf.ByteString; import net.sqlcipher.database.SQLiteDatabase; @@ -60,7 +59,7 @@ import org.session.libsession.messaging.sending_receiving.attachments.Attachment import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId; import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment; import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact; -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview; import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel; import org.session.libsession.messaging.threads.Address; import org.session.libsession.messaging.threads.recipients.Recipient; 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 91e11037f0..d3cb7a874c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/database/Storage.kt @@ -15,8 +15,8 @@ import org.session.libsession.messaging.messages.visible.VisibleMessage import org.session.libsession.messaging.open_groups.OpenGroup import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment -import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview +import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel import org.session.libsession.messaging.threads.Address import org.session.libsession.messaging.threads.Address.Companion.fromSerialized diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java index 7088818889..f67dacb56f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/MediaMmsMessageRecord.java @@ -23,7 +23,7 @@ import android.text.SpannableString; import network.loki.messenger.R; import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact; -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview; import org.thoughtcrime.securesms.database.MmsDatabase; import org.thoughtcrime.securesms.database.SmsDatabase.Status; import org.session.libsession.database.documents.IdentityKeyMismatch; 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 55b8642827..8380c41633 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 @@ -25,7 +25,7 @@ import android.text.style.StyleSpan; import network.loki.messenger.R; -import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage; +import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage; import org.session.libsession.messaging.utilities.ClosedGroupUpdateMessageBuilder; import org.session.libsession.messaging.utilities.ClosedGroupUpdateMessageData; import org.thoughtcrime.securesms.database.MmsSmsColumns; diff --git a/app/src/main/java/org/thoughtcrime/securesms/database/model/MmsMessageRecord.java b/app/src/main/java/org/thoughtcrime/securesms/database/model/MmsMessageRecord.java index 6b88fdfbd0..0bfd330985 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/database/model/MmsMessageRecord.java +++ b/app/src/main/java/org/thoughtcrime/securesms/database/model/MmsMessageRecord.java @@ -5,7 +5,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact; -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview; import org.session.libsession.messaging.threads.recipients.Recipient; import org.session.libsession.database.documents.IdentityKeyMismatch; diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java index eae25110b0..e60d5821af 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java +++ b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewRepository.java @@ -25,7 +25,7 @@ import org.thoughtcrime.securesms.linkpreview.LinkPreviewUtil.OpenGraph; import org.session.libsession.messaging.sending_receiving.attachments.Attachment; import org.session.libsession.messaging.sending_receiving.attachments.UriAttachment; -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview; import org.session.libsession.utilities.concurrent.SignalExecutors; import java.io.ByteArrayOutputStream; diff --git a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewViewModel.java b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewViewModel.java index 60c6431906..6947801ec5 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewViewModel.java +++ b/app/src/main/java/org/thoughtcrime/securesms/linkpreview/LinkPreviewViewModel.java @@ -13,9 +13,8 @@ import org.session.libsession.utilities.Debouncer; import org.session.libsession.utilities.Util; import org.session.libsignal.libsignal.util.guava.Optional; -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview; -import java.util.Collections; import java.util.List; diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocolV2.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocolV2.kt index df1d7c0b52..5f61506504 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocolV2.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/protocol/ClosedGroupsProtocolV2.kt @@ -31,6 +31,7 @@ import org.session.libsession.utilities.TextSecurePreferences import java.util.* object ClosedGroupsProtocolV2 { + @JvmStatic fun handleMessage(context: Context, closedGroupUpdate: DataMessage.ClosedGroupControlMessage, sentTimestamp: Long, groupPublicKey: String, senderPublicKey: String) { if (!isValid(context, closedGroupUpdate, senderPublicKey, sentTimestamp)) { return } @@ -40,7 +41,6 @@ object ClosedGroupsProtocolV2 { DataMessage.ClosedGroupControlMessage.Type.MEMBERS_ADDED -> handleClosedGroupMembersAdded(context, closedGroupUpdate, sentTimestamp, groupPublicKey, senderPublicKey) DataMessage.ClosedGroupControlMessage.Type.NAME_CHANGE -> handleClosedGroupNameChange(context, closedGroupUpdate, sentTimestamp, groupPublicKey, senderPublicKey) DataMessage.ClosedGroupControlMessage.Type.MEMBER_LEFT -> handleClosedGroupMemberLeft(context, sentTimestamp, groupPublicKey, senderPublicKey) - DataMessage.ClosedGroupControlMessage.Type.UPDATE -> handleClosedGroupUpdate(context, closedGroupUpdate, sentTimestamp, groupPublicKey, senderPublicKey) DataMessage.ClosedGroupControlMessage.Type.ENCRYPTION_KEY_PAIR -> handleGroupEncryptionKeyPair(context, closedGroupUpdate, groupPublicKey, senderPublicKey) else -> { Log.d("Loki","Can't handle closed group update of unknown type: ${closedGroupUpdate.type}") @@ -64,7 +64,6 @@ object ClosedGroupsProtocolV2 { DataMessage.ClosedGroupControlMessage.Type.MEMBER_LEFT -> { senderPublicKey.isNotEmpty() } - DataMessage.ClosedGroupControlMessage.Type.UPDATE, DataMessage.ClosedGroupControlMessage.Type.NAME_CHANGE -> { !closedGroupUpdate.name.isNullOrEmpty() } diff --git a/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt b/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt index f1f8d8c49c..b905d25cda 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/StorageProtocol.kt @@ -11,9 +11,9 @@ import org.session.libsession.messaging.messages.visible.Attachment import org.session.libsession.messaging.messages.visible.VisibleMessage import org.session.libsession.messaging.open_groups.OpenGroup import org.session.libsession.messaging.sending_receiving.attachments.AttachmentId -import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage +import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel import org.session.libsession.messaging.threads.Address import org.session.libsession.messaging.threads.GroupRecord diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/signal/IncomingMediaMessage.java b/libsession/src/main/java/org/session/libsession/messaging/messages/signal/IncomingMediaMessage.java index f235e84e92..ed4b8b6df8 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/signal/IncomingMediaMessage.java +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/signal/IncomingMediaMessage.java @@ -3,10 +3,10 @@ package org.session.libsession.messaging.messages.signal; import org.session.libsession.messaging.messages.visible.VisibleMessage; import org.session.libsession.messaging.sending_receiving.attachments.Attachment; import org.session.libsession.messaging.sending_receiving.attachments.PointerAttachment; -import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage; +import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage; import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact; import org.session.libsession.messaging.threads.Address; -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview; import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel; import org.session.libsession.utilities.GroupUtil; import org.session.libsignal.libsignal.util.guava.Optional; diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingGroupMediaMessage.java b/libsession/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingGroupMediaMessage.java index 574c47cd19..d8a213cfcf 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingGroupMediaMessage.java +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingGroupMediaMessage.java @@ -6,14 +6,10 @@ import androidx.annotation.Nullable; import org.session.libsession.messaging.threads.DistributionTypes; import org.session.libsession.messaging.sending_receiving.attachments.Attachment; import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact; -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview; import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel; import org.session.libsession.messaging.threads.recipients.Recipient; -import org.session.libsignal.utilities.Base64; -import org.session.libsignal.service.internal.push.SignalServiceProtos.GroupContext; - -import java.io.IOException; import java.util.LinkedList; import java.util.List; diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingMediaMessage.java b/libsession/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingMediaMessage.java index d8d4dff3c5..b056bd0c19 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingMediaMessage.java +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingMediaMessage.java @@ -9,7 +9,7 @@ import org.session.libsession.database.documents.IdentityKeyMismatch; import org.session.libsession.database.documents.NetworkFailure; import org.session.libsession.messaging.sending_receiving.attachments.Attachment; import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact; -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview; import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel; import org.session.libsession.messaging.threads.recipients.Recipient; diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingSecureMediaMessage.java b/libsession/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingSecureMediaMessage.java index 8b5e7ddef0..f079914700 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingSecureMediaMessage.java +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/signal/OutgoingSecureMediaMessage.java @@ -5,7 +5,7 @@ import androidx.annotation.Nullable; import org.session.libsession.messaging.sending_receiving.attachments.Attachment; import org.session.libsession.messaging.sending_receiving.sharecontacts.Contact; -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview; +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview; import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel; import org.session.libsession.messaging.threads.recipients.Recipient; diff --git a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/LinkPreview.kt b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/LinkPreview.kt index 63395bb155..a292bf7c6a 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/messages/visible/LinkPreview.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/messages/visible/LinkPreview.kt @@ -1,7 +1,7 @@ package org.session.libsession.messaging.messages.visible import org.session.libsession.messaging.MessagingModuleConfiguration -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview as SignalLinkPreiview +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview as SignalLinkPreiview import org.session.libsignal.utilities.logging.Log import org.session.libsignal.service.internal.push.SignalServiceProtos diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiver.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiver.kt index 20d21053fb..b09a016722 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiver.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiver.kt @@ -63,13 +63,13 @@ object MessageReceiver { sender = envelope.source } else { when (envelope.type) { - SignalServiceProtos.Envelope.Type.UNIDENTIFIED_SENDER -> { + SignalServiceProtos.Envelope.Type.SESSION_MESSAGE -> { val userX25519KeyPair = MessagingModuleConfiguration.shared.storage.getUserX25519KeyPair() val decryptionResult = MessageReceiverDecryption.decryptWithSessionProtocol(ciphertext.toByteArray(), userX25519KeyPair) plaintext = decryptionResult.first sender = decryptionResult.second } - SignalServiceProtos.Envelope.Type.CLOSED_GROUP_CIPHERTEXT -> { + SignalServiceProtos.Envelope.Type.CLOSED_GROUP_MESSAGE -> { val hexEncodedGroupPublicKey = envelope.source if (hexEncodedGroupPublicKey == null || !MessagingModuleConfiguration.shared.storage.isClosedGroup(hexEncodedGroupPublicKey)) { throw Error.InvalidGroupPublicKey @@ -107,12 +107,12 @@ object MessageReceiver { val proto = SignalServiceProtos.Content.parseFrom(PushTransportDetails.getStrippedPaddingMessageBody(plaintext)) // Parse the message val message: Message = ReadReceipt.fromProto(proto) ?: - TypingIndicator.fromProto(proto) ?: - ClosedGroupControlMessage.fromProto(proto) ?: - DataExtractionNotification.fromProto(proto) ?: - ExpirationTimerUpdate.fromProto(proto) ?: - ConfigurationMessage.fromProto(proto) ?: - VisibleMessage.fromProto(proto) ?: throw Error.UnknownMessage + TypingIndicator.fromProto(proto) ?: + ClosedGroupControlMessage.fromProto(proto) ?: + DataExtractionNotification.fromProto(proto) ?: + ExpirationTimerUpdate.fromProto(proto) ?: + ConfigurationMessage.fromProto(proto) ?: + VisibleMessage.fromProto(proto) ?: throw Error.UnknownMessage // Ignore self sends if needed if (!message.isSelfSendValid && sender == userPublicKey) throw Error.SelfSend // Guard against control messages in open groups diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt index 20f860c18c..a09ff9d9ce 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt @@ -27,7 +27,7 @@ import org.session.libsignal.service.loki.utilities.hexEncodedPublicKey import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.logging.Log import org.session.libsession.messaging.sending_receiving.attachments.Attachment as SignalAttachment -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview as SignalLinkPreview +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview as SignalLinkPreview import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel as SignalQuote object MessageSender { diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroup.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroupHandler.kt similarity index 100% rename from libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroup.kt rename to libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSenderClosedGroupHandler.kt diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt similarity index 99% rename from libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt rename to libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt index 44d3013b13..47f99bcb54 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageReceiverHandler.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/ReceivedMessageHandler.kt @@ -9,8 +9,8 @@ import org.session.libsession.messaging.messages.control.* import org.session.libsession.messaging.messages.visible.Attachment import org.session.libsession.messaging.messages.visible.VisibleMessage import org.session.libsession.messaging.sending_receiving.attachments.PointerAttachment -import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage -import org.session.libsession.messaging.sending_receiving.linkpreview.LinkPreview +import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage +import org.session.libsession.messaging.sending_receiving.link_preview.LinkPreview import org.session.libsession.messaging.sending_receiving.notifications.PushNotificationAPI import org.session.libsession.messaging.sending_receiving.quotes.QuoteModel import org.session.libsession.messaging.threads.Address diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/dataextraction/DataExtractionNotificationInfoMessage.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/data_extraction/DataExtractionNotificationInfoMessage.kt similarity index 73% rename from libsession/src/main/java/org/session/libsession/messaging/sending_receiving/dataextraction/DataExtractionNotificationInfoMessage.kt rename to libsession/src/main/java/org/session/libsession/messaging/sending_receiving/data_extraction/DataExtractionNotificationInfoMessage.kt index aca360eca6..cba0b7a805 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/dataextraction/DataExtractionNotificationInfoMessage.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/data_extraction/DataExtractionNotificationInfoMessage.kt @@ -1,4 +1,4 @@ -package org.session.libsession.messaging.sending_receiving.dataextraction +package org.session.libsession.messaging.sending_receiving.data_extraction class DataExtractionNotificationInfoMessage { diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/linkpreview/LinkPreview.java b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/link_preview/LinkPreview.java similarity index 96% rename from libsession/src/main/java/org/session/libsession/messaging/sending_receiving/linkpreview/LinkPreview.java rename to libsession/src/main/java/org/session/libsession/messaging/sending_receiving/link_preview/LinkPreview.java index dda9004b45..4a644b2e9b 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/linkpreview/LinkPreview.java +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/link_preview/LinkPreview.java @@ -1,4 +1,4 @@ -package org.session.libsession.messaging.sending_receiving.linkpreview; +package org.session.libsession.messaging.sending_receiving.link_preview; import androidx.annotation.NonNull; import androidx.annotation.Nullable; diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/OpenGroupPoller.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/OpenGroupPoller.kt index b94cb07e21..acf7e23d4d 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/OpenGroupPoller.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/OpenGroupPoller.kt @@ -43,10 +43,10 @@ class OpenGroupPoller(private val openGroup: OpenGroup, private val executorServ fun startIfNeeded() { if (hasStarted || executorService == null) return cancellableFutures += listOf( - executorService.scheduleAtFixedRate(::pollForNewMessages,0, pollForNewMessagesInterval, TimeUnit.MILLISECONDS), - executorService.scheduleAtFixedRate(::pollForDeletedMessages,0, pollForDeletedMessagesInterval, TimeUnit.MILLISECONDS), - executorService.scheduleAtFixedRate(::pollForModerators,0, pollForModeratorsInterval, TimeUnit.MILLISECONDS), - executorService.scheduleAtFixedRate(::pollForDisplayNames,0, pollForDisplayNamesInterval, TimeUnit.MILLISECONDS) + executorService.scheduleAtFixedRate(::pollForNewMessages,0, pollForNewMessagesInterval, TimeUnit.MILLISECONDS), + executorService.scheduleAtFixedRate(::pollForDeletedMessages,0, pollForDeletedMessagesInterval, TimeUnit.MILLISECONDS), + executorService.scheduleAtFixedRate(::pollForModerators,0, pollForModeratorsInterval, TimeUnit.MILLISECONDS), + executorService.scheduleAtFixedRate(::pollForDisplayNames,0, pollForDisplayNamesInterval, TimeUnit.MILLISECONDS) ) hasStarted = true } @@ -62,10 +62,10 @@ class OpenGroupPoller(private val openGroup: OpenGroup, private val executorServ // region Polling fun pollForNewMessages(): Promise { - return pollForNewMessages(false) + return pollForNewMessagesInternal(false) } - private fun pollForNewMessages(isBackgroundPoll: Boolean): Promise { + private fun pollForNewMessagesInternal(isBackgroundPoll: Boolean): Promise { if (isPollOngoing) { return Promise.of(Unit) } isPollOngoing = true val deferred = deferred() @@ -164,7 +164,7 @@ class OpenGroupPoller(private val openGroup: OpenGroup, private val executorServ content.setDataMessage(dataMessageProto.build()) // Envelope val builder = Envelope.newBuilder() - builder.type = Envelope.Type.UNIDENTIFIED_SENDER + builder.type = Envelope.Type.SESSION_MESSAGE builder.source = senderPublicKey builder.sourceDevice = 1 builder.setContent(content.build().toByteString()) diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/quotes/QuoteModel.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/quotes/QuoteModel.kt index c56774e351..fe4d8d6b21 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/quotes/QuoteModel.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/quotes/QuoteModel.kt @@ -4,8 +4,7 @@ import org.session.libsession.messaging.sending_receiving.attachments.Attachment import org.session.libsession.messaging.threads.Address class QuoteModel(val id: Long, - val author: Address, - val text: String, - val missing: Boolean, - val attachments: List?) { -} + val author: Address, + val text: String, + val missing: Boolean, + val attachments: List?) diff --git a/libsession/src/main/java/org/session/libsession/messaging/utilities/ClosedGroupUpdateMessageBuilder.kt b/libsession/src/main/java/org/session/libsession/messaging/utilities/ClosedGroupUpdateMessageBuilder.kt index 3393d50b99..33a6385692 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/utilities/ClosedGroupUpdateMessageBuilder.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/utilities/ClosedGroupUpdateMessageBuilder.kt @@ -3,7 +3,7 @@ package org.session.libsession.messaging.utilities import android.content.Context import org.session.libsession.R import org.session.libsession.messaging.MessagingModuleConfiguration -import org.session.libsession.messaging.sending_receiving.dataextraction.DataExtractionNotificationInfoMessage +import org.session.libsession.messaging.sending_receiving.data_extraction.DataExtractionNotificationInfoMessage import org.session.libsession.utilities.ExpirationUtil object ClosedGroupUpdateMessageBuilder { From fdede1c656239543a0b6d8266e6fc67afb678ebb Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Mon, 26 Apr 2021 11:39:23 +1000 Subject: [PATCH 08/13] Clean --- .../attachments/DatabaseAttachmentProvider.kt | 6 +- .../securesms/loki/activities/HomeActivity.kt | 4 +- .../securesms/loki/activities/PathActivity.kt | 2 +- .../loki/database/LokiAPIDatabase.kt | 2 +- .../database/MessageDataProvider.kt | 2 + .../messaging}/mentions/MentionsManager.kt | 15 +- .../messaging/open_groups/OpenGroup.kt | 4 - .../sending_receiving/pollers/Poller.kt | 2 +- .../libsession/snode/OnionRequestAPI.kt | 4 +- .../org/session/libsession/snode/SnodeAPI.kt | 2 +- .../libsession/snode/StorageProtocol.kt | 2 + .../messages/SignalServiceDataMessage.java | 3 +- .../messages/SignalServiceReceiptMessage.java | 4 +- .../messages/SignalServiceTypingMessage.java | 4 +- .../session/libsignal/service/loki}/Snode.kt | 4 +- .../service/loki/api/MessageWrapper.kt | 84 --------- .../libsignal/service/loki/api/Snode.kt | 34 ---- .../service/loki/api/opengroups/PublicChat.kt | 37 ---- .../loki/api/opengroups/PublicChatInfo.kt | 7 - .../loki/api/opengroups/PublicChatMessage.kt | 178 ------------------ .../loki/api/utilities/DecryptionUtilities.kt | 19 -- .../loki/api/utilities/EncryptionUtilities.kt | 45 ----- .../loki/database/LokiAPIDatabaseProtocol.kt | 2 +- .../database/LokiThreadDatabaseProtocol.kt | 11 -- .../service/loki/utilities/TTLUtilities.kt | 38 ---- 25 files changed, 31 insertions(+), 484 deletions(-) rename {libsignal/src/main/java/org/session/libsignal/service/loki/utilities => libsession/src/main/java/org/session/libsession/messaging}/mentions/MentionsManager.kt (78%) rename {libsession/src/main/java/org/session/libsession/snode => libsignal/src/main/java/org/session/libsignal/service/loki}/Snode.kt (87%) delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/api/MessageWrapper.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/api/Snode.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/api/opengroups/PublicChat.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/api/opengroups/PublicChatInfo.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/api/opengroups/PublicChatMessage.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/api/utilities/DecryptionUtilities.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/api/utilities/EncryptionUtilities.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/database/LokiThreadDatabaseProtocol.kt delete mode 100644 libsignal/src/main/java/org/session/libsignal/service/loki/utilities/TTLUtilities.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt b/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt index 963b6c1299..c582f909e1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/attachments/DatabaseAttachmentProvider.kt @@ -5,6 +5,7 @@ import android.text.TextUtils import com.google.protobuf.ByteString import org.greenrobot.eventbus.EventBus import org.session.libsession.database.MessageDataProvider +import org.session.libsession.messaging.open_groups.OpenGroup import org.session.libsession.messaging.sending_receiving.attachments.* import org.session.libsession.messaging.threads.Address import org.session.libsession.messaging.utilities.DotNetAPI @@ -26,7 +27,6 @@ import org.thoughtcrime.securesms.util.MediaUtil import java.io.IOException import java.io.InputStream - class DatabaseAttachmentProvider(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), MessageDataProvider { override fun getAttachmentStream(attachmentId: Long): SessionServiceAttachmentStream? { @@ -104,6 +104,10 @@ class DatabaseAttachmentProvider(context: Context, helper: SQLCipherOpenHelper) return smsDatabase.isOutgoingMessage(timestamp) || mmsDatabase.isOutgoingMessage(timestamp) } + override fun getOpenGroup(threadID: Long): OpenGroup? { + return null // TODO: Implement + } + override fun updateAttachmentAfterUploadSucceeded(attachmentId: Long, attachmentStream: SignalServiceAttachmentStream, attachmentKey: ByteArray, uploadResult: DotNetAPI.UploadResult) { val database = DatabaseFactory.getAttachmentDatabase(context) val databaseAttachment = getDatabaseAttachment(attachmentId) ?: return diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt index a8ed5f2c74..b458241798 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/HomeActivity.kt @@ -30,10 +30,10 @@ import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode import org.session.libsession.messaging.jobs.JobQueue +import org.session.libsession.messaging.mentions.MentionsManager import org.session.libsession.messaging.open_groups.OpenGroupAPI import org.session.libsession.messaging.sending_receiving.MessageSender import org.session.libsession.utilities.* -import org.session.libsignal.service.loki.utilities.mentions.MentionsManager import org.session.libsignal.service.loki.utilities.toHexString import org.session.libsignal.utilities.ThreadUtils import org.thoughtcrime.securesms.ApplicationContext @@ -139,7 +139,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity(), val userDB = DatabaseFactory.getLokiUserDatabase(this) val userPublicKey = TextSecurePreferences.getLocalNumber(this) if (userPublicKey != null) { - MentionsManager.configureIfNeeded(userPublicKey, threadDB, userDB) + MentionsManager.configureIfNeeded(userPublicKey, userDB) application.publicChatManager.startPollersIfNeeded() JobQueue.shared.resumePendingJobs() } diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/PathActivity.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/PathActivity.kt index 482a276328..f4f708aeda 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/activities/PathActivity.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/activities/PathActivity.kt @@ -24,7 +24,7 @@ import org.thoughtcrime.securesms.PassphraseRequiredActionBarActivity import org.thoughtcrime.securesms.loki.utilities.* import org.thoughtcrime.securesms.loki.views.GlowViewUtilities import org.thoughtcrime.securesms.loki.views.PathDotView -import org.session.libsignal.service.loki.api.Snode +import org.session.libsignal.service.loki.Snode class PathActivity : PassphraseRequiredActionBarActivity() { private val broadcastReceivers = mutableListOf() diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiAPIDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiAPIDatabase.kt index a9325a5527..58b9aeeec7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiAPIDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiAPIDatabase.kt @@ -7,7 +7,7 @@ import org.session.libsession.utilities.TextSecurePreferences import org.session.libsignal.libsignal.ecc.DjbECPrivateKey import org.session.libsignal.libsignal.ecc.DjbECPublicKey import org.session.libsignal.libsignal.ecc.ECKeyPair -import org.session.libsignal.service.loki.api.Snode +import org.session.libsignal.service.loki.Snode import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol import org.session.libsignal.service.loki.utilities.PublicKeyValidation import org.session.libsignal.service.loki.utilities.removing05PrefixIfNeeded diff --git a/libsession/src/main/java/org/session/libsession/database/MessageDataProvider.kt b/libsession/src/main/java/org/session/libsession/database/MessageDataProvider.kt index f28001cc7c..1584f41de4 100644 --- a/libsession/src/main/java/org/session/libsession/database/MessageDataProvider.kt +++ b/libsession/src/main/java/org/session/libsession/database/MessageDataProvider.kt @@ -1,5 +1,6 @@ package org.session.libsession.database +import org.session.libsession.messaging.open_groups.OpenGroup import org.session.libsession.messaging.sending_receiving.attachments.* import org.session.libsession.messaging.threads.Address import org.session.libsession.messaging.utilities.DotNetAPI @@ -37,4 +38,5 @@ interface MessageDataProvider { fun getAttachmentIDsFor(messageID: Long): List fun getLinkPreviewAttachmentIDFor(messageID: Long): Long? + fun getOpenGroup(threadID: Long): OpenGroup? } \ No newline at end of file diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/mentions/MentionsManager.kt b/libsession/src/main/java/org/session/libsession/messaging/mentions/MentionsManager.kt similarity index 78% rename from libsignal/src/main/java/org/session/libsignal/service/loki/utilities/mentions/MentionsManager.kt rename to libsession/src/main/java/org/session/libsession/messaging/mentions/MentionsManager.kt index 2edf6f677c..715204825a 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/mentions/MentionsManager.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/mentions/MentionsManager.kt @@ -1,19 +1,20 @@ -package org.session.libsignal.service.loki.utilities.mentions +package org.session.libsession.messaging.mentions + +import org.session.libsession.messaging.MessagingModuleConfiguration +import org.session.libsignal.service.loki.utilities.mentions.Mention -import org.session.libsignal.service.loki.database.LokiThreadDatabaseProtocol import org.session.libsignal.service.loki.database.LokiUserDatabaseProtocol -class MentionsManager(private val userPublicKey: String, private val threadDatabase: LokiThreadDatabaseProtocol, - private val userDatabase: LokiUserDatabaseProtocol) { +class MentionsManager(private val userPublicKey: String, private val userDatabase: LokiUserDatabaseProtocol) { var userPublicKeyCache = mutableMapOf>() // Thread ID to set of user hex encoded public keys companion object { public lateinit var shared: MentionsManager - public fun configureIfNeeded(userPublicKey: String, threadDatabase: LokiThreadDatabaseProtocol, userDatabase: LokiUserDatabaseProtocol) { + public fun configureIfNeeded(userPublicKey: String, userDatabase: LokiUserDatabaseProtocol) { if (::shared.isInitialized) { return; } - shared = MentionsManager(userPublicKey, threadDatabase, userDatabase) + shared = MentionsManager(userPublicKey, userDatabase) } } @@ -30,7 +31,7 @@ class MentionsManager(private val userPublicKey: String, private val threadDatab // Prepare val cache = userPublicKeyCache[threadID] ?: return listOf() // Gather candidates - val publicChat = threadDatabase.getPublicChat(threadID) + val publicChat = MessagingModuleConfiguration.shared.messageDataProvider.getOpenGroup(threadID) var candidates: List = cache.mapNotNull { publicKey -> val displayName: String? if (publicChat != null) { diff --git a/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroup.kt b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroup.kt index cf89c9009e..a39b22ad35 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroup.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroup.kt @@ -1,6 +1,5 @@ package org.session.libsession.messaging.open_groups -import org.session.libsignal.service.loki.api.opengroups.PublicChat import org.session.libsignal.utilities.JsonUtil data class OpenGroup( @@ -14,9 +13,6 @@ data class OpenGroup( companion object { - @JvmStatic fun from(publicChat: PublicChat): OpenGroup = - OpenGroup(publicChat.channel, publicChat.server, publicChat.displayName, publicChat.isDeletable) - @JvmStatic fun getId(channel: Long, server: String): String { return "$server.$channel" } diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt index d8187bad03..cbbb1b831c 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt @@ -8,7 +8,7 @@ import org.session.libsession.messaging.jobs.MessageReceiveJob import org.session.libsession.messaging.utilities.MessageWrapper import org.session.libsession.snode.SnodeAPI import org.session.libsession.snode.SnodeModule -import org.session.libsignal.service.loki.api.Snode +import org.session.libsignal.service.loki.Snode import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.logging.Log import java.security.SecureRandom diff --git a/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt b/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt index 4447c494e5..6a9bd70fdf 100644 --- a/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt +++ b/libsession/src/main/java/org/session/libsession/snode/OnionRequestAPI.kt @@ -11,7 +11,7 @@ import org.session.libsession.utilities.AESGCM import org.session.libsignal.utilities.logging.Log import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.* -import org.session.libsignal.service.loki.api.Snode +import org.session.libsignal.service.loki.Snode import org.session.libsignal.service.loki.api.utilities.* import org.session.libsession.utilities.AESGCM.EncryptionResult import org.session.libsignal.utilities.ThreadUtils @@ -79,7 +79,7 @@ object OnionRequestAPI { ) internal sealed class Destination { - class Snode(val snode: org.session.libsignal.service.loki.api.Snode) : Destination() + class Snode(val snode: org.session.libsignal.service.loki.Snode) : Destination() class Server(val host: String, val target: String, val x25519PublicKey: String) : Destination() } diff --git a/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt b/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt index 1d90331e9a..5a0baa90b5 100644 --- a/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt +++ b/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt @@ -7,7 +7,7 @@ import nl.komponents.kovenant.* import nl.komponents.kovenant.functional.bind import nl.komponents.kovenant.functional.map import org.session.libsession.snode.utilities.getRandomElement -import org.session.libsignal.service.loki.api.Snode +import org.session.libsignal.service.loki.Snode import org.session.libsignal.service.loki.api.utilities.HTTP import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol import org.session.libsignal.service.loki.utilities.Broadcaster diff --git a/libsession/src/main/java/org/session/libsession/snode/StorageProtocol.kt b/libsession/src/main/java/org/session/libsession/snode/StorageProtocol.kt index 85ab507114..7e0d103974 100644 --- a/libsession/src/main/java/org/session/libsession/snode/StorageProtocol.kt +++ b/libsession/src/main/java/org/session/libsession/snode/StorageProtocol.kt @@ -1,5 +1,7 @@ package org.session.libsession.snode +import org.session.libsignal.service.loki.Snode + interface SnodeStorageProtocol { fun getSnodePool(): Set diff --git a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceDataMessage.java b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceDataMessage.java index cbc8c8fafe..f65568bc42 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceDataMessage.java +++ b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceDataMessage.java @@ -10,7 +10,6 @@ import org.session.libsignal.libsignal.util.guava.Optional; import org.session.libsignal.service.api.messages.shared.SharedContact; import org.session.libsignal.service.api.push.SignalServiceAddress; import org.session.libsignal.service.internal.push.SignalServiceProtos.DataMessage.ClosedGroupControlMessage; -import org.session.libsignal.service.loki.utilities.TTLUtilities; import java.util.LinkedList; import java.util.List; @@ -247,7 +246,7 @@ public class SignalServiceDataMessage { } public int getTTL() { - return TTLUtilities.getTTL(TTLUtilities.MessageType.Regular); + return 0; } public static class Builder { diff --git a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceReceiptMessage.java b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceReceiptMessage.java index 8e48450011..83d891eb78 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceReceiptMessage.java +++ b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceReceiptMessage.java @@ -1,8 +1,6 @@ package org.session.libsignal.service.api.messages; -import org.session.libsignal.service.loki.utilities.TTLUtilities; - import java.util.List; public class SignalServiceReceiptMessage { @@ -41,5 +39,5 @@ public class SignalServiceReceiptMessage { return type == Type.READ; } - public int getTTL() { return TTLUtilities.getTTL(TTLUtilities.MessageType.Receipt); } + public int getTTL() { return 0; } } diff --git a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceTypingMessage.java b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceTypingMessage.java index d3fb3a2fc0..81a4879ffc 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceTypingMessage.java +++ b/libsignal/src/main/java/org/session/libsignal/service/api/messages/SignalServiceTypingMessage.java @@ -1,7 +1,5 @@ package org.session.libsignal.service.api.messages; -import org.session.libsignal.service.loki.utilities.TTLUtilities; - public class SignalServiceTypingMessage { public enum Action { @@ -32,5 +30,5 @@ public class SignalServiceTypingMessage { return action == Action.STOPPED; } - public int getTTL() { return TTLUtilities.getTTL(TTLUtilities.MessageType.TypingIndicator); } + public int getTTL() { return 0; } } diff --git a/libsession/src/main/java/org/session/libsession/snode/Snode.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/Snode.kt similarity index 87% rename from libsession/src/main/java/org/session/libsession/snode/Snode.kt rename to libsignal/src/main/java/org/session/libsignal/service/loki/Snode.kt index 2bb2429eca..8c4f22854f 100644 --- a/libsession/src/main/java/org/session/libsession/snode/Snode.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/Snode.kt @@ -1,9 +1,9 @@ -package org.session.libsession.snode +package org.session.libsignal.service.loki class Snode(val address: String, val port: Int, val publicKeySet: KeySet?) { val ip: String get() = address.removePrefix("https://") - internal enum class Method(val rawValue: String) { + public enum class Method(val rawValue: String) { GetSwarm("get_snodes_for_pubkey"), GetMessages("retrieve"), SendMessage("store") diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/MessageWrapper.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/MessageWrapper.kt deleted file mode 100644 index 2cb8dd0440..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/MessageWrapper.kt +++ /dev/null @@ -1,84 +0,0 @@ -package org.session.libsignal.service.loki.api - -import com.google.protobuf.ByteString -import org.session.libsignal.utilities.logging.Log -import org.session.libsignal.service.internal.push.SignalServiceProtos.Envelope -import org.session.libsignal.utilities.Base64 -import org.session.libsignal.service.internal.websocket.WebSocketProtos.WebSocketMessage -import org.session.libsignal.service.internal.websocket.WebSocketProtos.WebSocketRequestMessage -import java.security.SecureRandom - -object MessageWrapper { - - // region Types - sealed class Error(val description: String) : Exception() { - object FailedToWrapData : Error("Failed to wrap data.") - object FailedToWrapMessageInEnvelope : Error("Failed to wrap message in envelope.") - object FailedToWrapEnvelopeInWebSocketMessage : Error("Failed to wrap envelope in web socket message.") - object FailedToUnwrapData : Error("Failed to unwrap data.") - } - // endregion - - // region Wrapping - /** - * Wraps `message` in a `SignalServiceProtos.Envelope` and then a `WebSocketProtos.WebSocketMessage` to match the desktop application. - */ - fun wrap(message: SignalMessageInfo): ByteArray { - try { - val envelope = createEnvelope(message) - val webSocketMessage = createWebSocketMessage(envelope) - return webSocketMessage.toByteArray() - } catch (e: Exception) { - throw if (e is Error) { e } else { Error.FailedToWrapData } - } - } - - private fun createEnvelope(message: SignalMessageInfo): Envelope { - try { - val builder = Envelope.newBuilder() - builder.type = message.type - builder.timestamp = message.timestamp - builder.source = message.senderPublicKey - builder.sourceDevice = message.senderDeviceID - builder.content = ByteString.copyFrom(Base64.decode(message.content)) - return builder.build() - } catch (e: Exception) { - Log.d("Loki", "Failed to wrap message in envelope: ${e.message}.") - throw Error.FailedToWrapMessageInEnvelope - } - } - - private fun createWebSocketMessage(envelope: Envelope): WebSocketMessage { - try { - val requestBuilder = WebSocketRequestMessage.newBuilder() - requestBuilder.verb = "PUT" - requestBuilder.path = "/api/v1/message" - requestBuilder.id = SecureRandom.getInstance("SHA1PRNG").nextLong() - requestBuilder.body = envelope.toByteString() - val messageBuilder = WebSocketMessage.newBuilder() - messageBuilder.request = requestBuilder.build() - messageBuilder.type = WebSocketMessage.Type.REQUEST - return messageBuilder.build() - } catch (e: Exception) { - Log.d("Loki", "Failed to wrap envelope in web socket message: ${e.message}.") - throw Error.FailedToWrapEnvelopeInWebSocketMessage - } - } - // endregion - - // region Unwrapping - /** - * `data` shouldn't be base 64 encoded. - */ - fun unwrap(data: ByteArray): Envelope { - try { - val webSocketMessage = WebSocketMessage.parseFrom(data) - val envelopeAsData = webSocketMessage.request.body - return Envelope.parseFrom(envelopeAsData) - } catch (e: Exception) { - Log.d("Loki", "Failed to unwrap data: ${e.message}.") - throw Error.FailedToUnwrapData - } - } - // endregion -} diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/Snode.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/Snode.kt deleted file mode 100644 index 72c0eb1d4d..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/Snode.kt +++ /dev/null @@ -1,34 +0,0 @@ -package org.session.libsignal.service.loki.api - -public class Snode(val address: String, val port: Int, val publicKeySet: KeySet?) { - - val ip: String get() = address.removePrefix("https://") - - enum class Method(val rawValue: String) { - /** - * Only supported by snode targets. - */ - GetSwarm("get_snodes_for_pubkey"), - /** - * Only supported by snode targets. - */ - GetMessages("retrieve"), - SendMessage("store") - } - - data class KeySet(val ed25519Key: String, val x25519Key: String) - - override fun equals(other: Any?): Boolean { - return if (other is Snode) { - address == other.address && port == other.port - } else { - false - } - } - - override fun hashCode(): Int { - return address.hashCode() xor port.hashCode() - } - - override fun toString(): String { return "$address:$port" } -} diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/opengroups/PublicChat.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/opengroups/PublicChat.kt deleted file mode 100644 index 1cf9ada3cc..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/opengroups/PublicChat.kt +++ /dev/null @@ -1,37 +0,0 @@ -package org.session.libsignal.service.loki.api.opengroups - -import org.session.libsignal.utilities.JsonUtil - -public data class PublicChat( - public val channel: Long, - private val serverURL: String, - public val displayName: String, - public val isDeletable: Boolean -) { - public val server get() = serverURL.toLowerCase() - public val id get() = getId(channel, server) - - companion object { - - @JvmStatic fun getId(channel: Long, server: String): String { - return "$server.$channel" - } - - @JvmStatic fun fromJSON(jsonAsString: String): PublicChat? { - try { - val json = JsonUtil.fromJson(jsonAsString) - val channel = json.get("channel").asLong() - val server = json.get("server").asText().toLowerCase() - val displayName = json.get("displayName").asText() - val isDeletable = json.get("isDeletable").asBoolean() - return PublicChat(channel, server, displayName, isDeletable) - } catch (e: Exception) { - return null - } - } - } - - public fun toJSON(): Map { - return mapOf( "channel" to channel, "server" to server, "displayName" to displayName, "isDeletable" to isDeletable ) - } -} diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/opengroups/PublicChatInfo.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/opengroups/PublicChatInfo.kt deleted file mode 100644 index 78395634fd..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/opengroups/PublicChatInfo.kt +++ /dev/null @@ -1,7 +0,0 @@ -package org.session.libsignal.service.loki.api.opengroups - -public data class PublicChatInfo ( - public val displayName: String, - public val profilePictureURL: String, - public val memberCount: Int -) diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/opengroups/PublicChatMessage.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/opengroups/PublicChatMessage.kt deleted file mode 100644 index 4fdc75a69a..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/opengroups/PublicChatMessage.kt +++ /dev/null @@ -1,178 +0,0 @@ -package org.session.libsignal.service.loki.api.opengroups - -import org.whispersystems.curve25519.Curve25519 -import org.session.libsignal.utilities.logging.Log -import org.session.libsignal.utilities.Hex -import org.session.libsignal.service.loki.utilities.removing05PrefixIfNeeded - -public data class PublicChatMessage( - public val serverID: Long?, - public val senderPublicKey: String, - public val displayName: String, - public val body: String, - public val timestamp: Long, - public val type: String, - public val quote: Quote?, - public val attachments: List, - public val profilePicture: ProfilePicture?, - public val signature: Signature?, - public val serverTimestamp: Long -) { - - // region Settings - companion object { - private val curve = Curve25519.getInstance(Curve25519.BEST) - private val signatureVersion: Long = 1 - private val attachmentType = "net.app.core.oembed" - } - // endregion - - // region Types - public data class ProfilePicture( - public val profileKey: ByteArray, - public val url: String - ) - - public data class Quote( - public val quotedMessageTimestamp: Long, - public val quoteePublicKey: String, - public val quotedMessageBody: String, - public val quotedMessageServerID: Long? = null - ) - - public data class Signature( - public val data: ByteArray, - public val version: Long - ) - - public data class Attachment( - public val kind: Kind, - public val server: String, - public val serverID: Long, - public val contentType: String, - public val size: Int, - public val fileName: String, - public val flags: Int, - public val width: Int, - public val height: Int, - public val caption: String?, - public val url: String, - /** - Guaranteed to be non-`nil` if `kind` is `LinkPreview`. - */ - public val linkPreviewURL: String?, - /** - Guaranteed to be non-`nil` if `kind` is `LinkPreview`. - */ - public val linkPreviewTitle: String? - ) { - public val dotNetAPIType = when { - contentType.startsWith("image") -> "photo" - contentType.startsWith("video") -> "video" - contentType.startsWith("audio") -> "audio" - else -> "other" - } - - public enum class Kind(val rawValue: String) { - Attachment("attachment"), LinkPreview("preview") - } - } - // endregion - - // region Initialization - constructor(hexEncodedPublicKey: String, displayName: String, body: String, timestamp: Long, type: String, quote: Quote?, attachments: List) - : this(null, hexEncodedPublicKey, displayName, body, timestamp, type, quote, attachments, null, null, 0) - // endregion - - // region Crypto - internal fun sign(privateKey: ByteArray): PublicChatMessage? { - val data = getValidationData(signatureVersion) - if (data == null) { - Log.d("Loki", "Failed to sign public chat message.") - return null - } - try { - val signatureData = curve.calculateSignature(privateKey, data) - val signature = Signature(signatureData, signatureVersion) - return copy(signature = signature) - } catch (e: Exception) { - Log.d("Loki", "Failed to sign public chat message due to error: ${e.message}.") - return null - } - } - - internal fun hasValidSignature(): Boolean { - if (signature == null) { return false } - val data = getValidationData(signature.version) ?: return false - val publicKey = Hex.fromStringCondensed(senderPublicKey.removing05PrefixIfNeeded()) - try { - return curve.verifySignature(publicKey, data, signature.data) - } catch (e: Exception) { - Log.d("Loki", "Failed to verify public chat message due to error: ${e.message}.") - return false - } - } - // endregion - - // region Parsing - internal fun toJSON(): Map { - val value = mutableMapOf( "timestamp" to timestamp ) - if (quote != null) { - value["quote"] = mapOf( "id" to quote.quotedMessageTimestamp, "author" to quote.quoteePublicKey, "text" to quote.quotedMessageBody ) - } - if (signature != null) { - value["sig"] = Hex.toStringCondensed(signature.data) - value["sigver"] = signature.version - } - val annotation = mapOf( "type" to type, "value" to value ) - val annotations = mutableListOf( annotation ) - attachments.forEach { attachment -> - val attachmentValue = mutableMapOf( - // Fields required by the .NET API - "version" to 1, - "type" to attachment.dotNetAPIType, - // Custom fields - "lokiType" to attachment.kind.rawValue, - "server" to attachment.server, - "id" to attachment.serverID, - "contentType" to attachment.contentType, - "size" to attachment.size, - "fileName" to attachment.fileName, - "flags" to attachment.flags, - "width" to attachment.width, - "height" to attachment.height, - "url" to attachment.url - ) - if (attachment.caption != null) { attachmentValue["caption"] = attachment.caption } - if (attachment.linkPreviewURL != null) { attachmentValue["linkPreviewUrl"] = attachment.linkPreviewURL } - if (attachment.linkPreviewTitle != null) { attachmentValue["linkPreviewTitle"] = attachment.linkPreviewTitle } - val attachmentAnnotation = mapOf( "type" to attachmentType, "value" to attachmentValue ) - annotations.add(attachmentAnnotation) - } - val result = mutableMapOf( "text" to body, "annotations" to annotations ) - if (quote?.quotedMessageServerID != null) { - result["reply_to"] = quote.quotedMessageServerID - } - return result - } - // endregion - - // region Convenience - private fun getValidationData(signatureVersion: Long): ByteArray? { - var string = "${body.trim()}$timestamp" - if (quote != null) { - string += "${quote.quotedMessageTimestamp}${quote.quoteePublicKey}${quote.quotedMessageBody.trim()}" - if (quote.quotedMessageServerID != null) { - string += "${quote.quotedMessageServerID}" - } - } - string += attachments.sortedBy { it.serverID }.map { it.serverID }.joinToString("") - string += "$signatureVersion" - try { - return string.toByteArray(Charsets.UTF_8) - } catch (exception: Exception) { - return null - } - } - // endregion -} diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/utilities/DecryptionUtilities.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/utilities/DecryptionUtilities.kt deleted file mode 100644 index 017a554b9d..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/utilities/DecryptionUtilities.kt +++ /dev/null @@ -1,19 +0,0 @@ -package org.session.libsignal.service.loki.api.utilities - -import javax.crypto.Cipher -import javax.crypto.spec.GCMParameterSpec -import javax.crypto.spec.SecretKeySpec - -internal object DecryptionUtilities { - - /** - * Sync. Don't call from the main thread. - */ - internal fun decryptUsingAESGCM(ivAndCiphertext: ByteArray, symmetricKey: ByteArray): ByteArray { - val iv = ivAndCiphertext.sliceArray(0 until EncryptionUtilities.ivSize) - val ciphertext = ivAndCiphertext.sliceArray(EncryptionUtilities.ivSize until ivAndCiphertext.count()) - val cipher = Cipher.getInstance("AES/GCM/NoPadding") - cipher.init(Cipher.DECRYPT_MODE, SecretKeySpec(symmetricKey, "AES"), GCMParameterSpec(EncryptionUtilities.gcmTagSize, iv)) - return cipher.doFinal(ciphertext) - } -} diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/api/utilities/EncryptionUtilities.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/api/utilities/EncryptionUtilities.kt deleted file mode 100644 index 3ffb480244..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/api/utilities/EncryptionUtilities.kt +++ /dev/null @@ -1,45 +0,0 @@ -package org.session.libsignal.service.loki.api.utilities - -import org.whispersystems.curve25519.Curve25519 -import org.session.libsignal.libsignal.util.ByteUtil -import org.session.libsignal.utilities.Hex -import org.session.libsignal.service.internal.util.Util -import javax.crypto.Cipher -import javax.crypto.Mac -import javax.crypto.spec.GCMParameterSpec -import javax.crypto.spec.SecretKeySpec - -internal data class EncryptionResult( - internal val ciphertext: ByteArray, - internal val symmetricKey: ByteArray, - internal val ephemeralPublicKey: ByteArray -) - -internal object EncryptionUtilities { - internal val gcmTagSize = 128 - internal val ivSize = 12 - - /** - * Sync. Don't call from the main thread. - */ - internal fun encryptUsingAESGCM(plaintext: ByteArray, symmetricKey: ByteArray): ByteArray { - val iv = Util.getSecretBytes(ivSize) - val cipher = Cipher.getInstance("AES/GCM/NoPadding") - cipher.init(Cipher.ENCRYPT_MODE, SecretKeySpec(symmetricKey, "AES"), GCMParameterSpec(gcmTagSize, iv)) - return ByteUtil.combine(iv, cipher.doFinal(plaintext)) - } - - /** - * Sync. Don't call from the main thread. - */ - internal fun encryptForX25519PublicKey(plaintext: ByteArray, hexEncodedX25519PublicKey: String): EncryptionResult { - val x25519PublicKey = Hex.fromStringCondensed(hexEncodedX25519PublicKey) - val ephemeralKeyPair = Curve25519.getInstance(Curve25519.BEST).generateKeyPair() - val ephemeralSharedSecret = Curve25519.getInstance(Curve25519.BEST).calculateAgreement(x25519PublicKey, ephemeralKeyPair.privateKey) - val mac = Mac.getInstance("HmacSHA256") - mac.init(SecretKeySpec("LOKI".toByteArray(), "HmacSHA256")) - val symmetricKey = mac.doFinal(ephemeralSharedSecret) - val ciphertext = encryptUsingAESGCM(plaintext, symmetricKey) - return EncryptionResult(ciphertext, symmetricKey, ephemeralKeyPair.publicKey) - } -} diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/database/LokiAPIDatabaseProtocol.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/database/LokiAPIDatabaseProtocol.kt index 0d24f218ba..d564706ee8 100644 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/database/LokiAPIDatabaseProtocol.kt +++ b/libsignal/src/main/java/org/session/libsignal/service/loki/database/LokiAPIDatabaseProtocol.kt @@ -1,7 +1,7 @@ package org.session.libsignal.service.loki.database import org.session.libsignal.libsignal.ecc.ECKeyPair -import org.session.libsignal.service.loki.api.Snode +import org.session.libsignal.service.loki.Snode import java.util.* interface LokiAPIDatabaseProtocol { diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/database/LokiThreadDatabaseProtocol.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/database/LokiThreadDatabaseProtocol.kt deleted file mode 100644 index 5eb69da655..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/database/LokiThreadDatabaseProtocol.kt +++ /dev/null @@ -1,11 +0,0 @@ -package org.session.libsignal.service.loki.database - -import org.session.libsignal.service.loki.api.opengroups.PublicChat - -interface LokiThreadDatabaseProtocol { - - fun getThreadID(publicKey: String): Long - fun getPublicChat(threadID: Long): PublicChat? - fun setPublicChat(publicChat: PublicChat, threadID: Long) - fun removePublicChat(threadID: Long) -} diff --git a/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/TTLUtilities.kt b/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/TTLUtilities.kt deleted file mode 100644 index c229a97423..0000000000 --- a/libsignal/src/main/java/org/session/libsignal/service/loki/utilities/TTLUtilities.kt +++ /dev/null @@ -1,38 +0,0 @@ -package org.session.libsignal.service.loki.utilities - -public object TTLUtilities { - - /** - * If a message type specifies an invalid TTL, this will be used. - */ - public val fallbackMessageTTL = 2 * 24 * 60 * 60 * 1000 - - public enum class MessageType { - // Unimportant control messages - Address, Call, TypingIndicator, Verified, - // Somewhat important control messages - DeviceLink, - // Important control messages - ClosedGroupUpdate, Ephemeral, SessionRequest, Receipt, Sync, DeviceUnlinkingRequest, - // Visible messages - Regular - } - - @JvmStatic - public fun getTTL(messageType: MessageType): Int { - val minuteInMs = 60 * 1000 - val hourInMs = 60 * minuteInMs - val dayInMs = 24 * hourInMs - return when (messageType) { - // Unimportant control messages - MessageType.Address, MessageType.Call, MessageType.TypingIndicator, MessageType.Verified -> 20 * 1000 - // Somewhat important control messages - MessageType.DeviceLink -> 1 * hourInMs - // Important control messages - MessageType.ClosedGroupUpdate, MessageType.Ephemeral, MessageType.SessionRequest, MessageType.Receipt, - MessageType.Sync, MessageType.DeviceUnlinkingRequest -> 2 * dayInMs - 1 * hourInMs - // Visible messages - MessageType.Regular -> 2 * dayInMs - } - } -} From 07fe672f318c76d22c75dad662a6cc7adbd330dd Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Mon, 26 Apr 2021 13:12:05 +1000 Subject: [PATCH 09/13] Clean --- .../loki/api/PublicChatInfoUpdateWorker.kt | 4 ++-- .../securesms/loki/api/PublicChatManager.kt | 7 +++---- .../loki/api/PushNotificationService.kt | 4 ++-- .../loki/database/LokiThreadDatabase.kt | 21 +++++++++---------- .../loki/utilities/MentionManagerUtilities.kt | 2 +- .../loki/utilities/OpenGroupUtilities.kt | 7 +++---- .../loki/views/ProfilePictureView.kt | 2 +- 7 files changed, 22 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/api/PublicChatInfoUpdateWorker.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/api/PublicChatInfoUpdateWorker.kt index 40955d86c5..c8f1a1f215 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/api/PublicChatInfoUpdateWorker.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/api/PublicChatInfoUpdateWorker.kt @@ -2,9 +2,9 @@ package org.thoughtcrime.securesms.loki.api import android.content.Context import androidx.work.* +import org.session.libsession.messaging.open_groups.OpenGroup import org.session.libsignal.utilities.logging.Log import org.thoughtcrime.securesms.loki.utilities.OpenGroupUtilities -import org.session.libsignal.service.loki.api.opengroups.PublicChat /** * Delegates the [OpenGroupUtilities.updateGroupInfo] call to the work manager. @@ -40,7 +40,7 @@ class PublicChatInfoUpdateWorker(val context: Context, params: WorkerParameters) val serverUrl = inputData.getString(DATA_KEY_SERVER_URL)!! val channel = inputData.getLong(DATA_KEY_CHANNEL, -1) - val publicChatId = PublicChat.getId(channel, serverUrl) + val publicChatId = OpenGroup.getId(channel, serverUrl) return try { Log.v(TAG, "Updating open group info for $publicChatId.") diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/api/PublicChatManager.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/api/PublicChatManager.kt index a7726bfee3..6586c45013 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/api/PublicChatManager.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/api/PublicChatManager.kt @@ -12,7 +12,6 @@ import org.session.libsession.messaging.open_groups.OpenGroupInfo import org.session.libsession.messaging.sending_receiving.pollers.OpenGroupPoller import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.Util -import org.session.libsignal.service.loki.api.opengroups.PublicChat import org.thoughtcrime.securesms.database.DatabaseContentProviders import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.groups.GroupManager @@ -75,7 +74,7 @@ class PublicChatManager(private val context: Context) { @WorkerThread public fun addChat(server: String, channel: Long, info: OpenGroupInfo): OpenGroup { - val chat = PublicChat(channel, server, info.displayName, true) + val chat = OpenGroup(channel, server, info.displayName, true) var threadID = GroupManager.getOpenGroupThreadID(chat.id, context) var profilePicture: Bitmap? = null // Create the group if we don't have one @@ -96,12 +95,12 @@ class PublicChatManager(private val context: Context) { // Start polling Util.runOnMain { startPollersIfNeeded() } - return OpenGroup.from(chat) + return chat } public fun removeChat(server: String, channel: Long) { val threadDB = DatabaseFactory.getThreadDatabase(context) - val groupId = PublicChat.getId(channel, server) + val groupId = OpenGroup.getId(channel, server) val threadId = GroupManager.getOpenGroupThreadID(groupId, context) val groupAddress = threadDB.getRecipientForThreadId(threadId)!!.address.serialize() GroupManager.deleteGroup(groupAddress, context) diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/api/PushNotificationService.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/api/PushNotificationService.kt index 0f5244ae19..5e5305103a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/api/PushNotificationService.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/api/PushNotificationService.kt @@ -6,8 +6,8 @@ import com.google.firebase.messaging.FirebaseMessagingService import com.google.firebase.messaging.RemoteMessage import org.session.libsession.messaging.jobs.JobQueue import org.session.libsession.messaging.jobs.MessageReceiveJob +import org.session.libsession.messaging.utilities.MessageWrapper import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsignal.service.loki.api.MessageWrapper import org.session.libsignal.utilities.Base64 import org.session.libsignal.utilities.logging.Log import org.thoughtcrime.securesms.notifications.NotificationChannels @@ -27,7 +27,7 @@ class PushNotificationService : FirebaseMessagingService() { val data = base64EncodedData?.let { Base64.decode(it) } if (data != null) { try { - JobQueue.shared.add(MessageReceiveJob(MessageWrapper.unwrap(data).toByteArray(),true)) + JobQueue.shared.add(MessageReceiveJob(MessageWrapper.unwrap(data),true)) } catch (e: Exception) { Log.d("Loki", "Failed to unwrap data for message due to error: $e.") } diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiThreadDatabase.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiThreadDatabase.kt index 0c2dff9a80..3f13eef929 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiThreadDatabase.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/database/LokiThreadDatabase.kt @@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.loki.database import android.content.ContentValues import android.content.Context import android.database.Cursor +import org.session.libsession.messaging.open_groups.OpenGroup import org.thoughtcrime.securesms.database.Database import org.thoughtcrime.securesms.database.DatabaseFactory @@ -12,13 +13,11 @@ import org.thoughtcrime.securesms.loki.utilities.* import org.session.libsession.messaging.threads.Address import org.session.libsession.messaging.threads.recipients.Recipient import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsignal.service.loki.api.opengroups.PublicChat import org.session.libsignal.utilities.JsonUtil -import org.session.libsignal.service.loki.database.LokiThreadDatabaseProtocol import org.session.libsignal.service.loki.utilities.PublicKeyValidation -class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), LokiThreadDatabaseProtocol { +class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper) { companion object { private val sessionResetTable = "loki_thread_session_reset_database" @@ -31,22 +30,22 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa @JvmStatic val createPublicChatTableCommand = "CREATE TABLE $publicChatTable ($threadID INTEGER PRIMARY KEY, $publicChat TEXT);" } - override fun getThreadID(hexEncodedPublicKey: String): Long { + fun getThreadID(hexEncodedPublicKey: String): Long { val address = Address.fromSerialized(hexEncodedPublicKey) val recipient = Recipient.from(context, address, false) return DatabaseFactory.getThreadDatabase(context).getOrCreateThreadIdFor(recipient) } - fun getAllPublicChats(): Map { + fun getAllPublicChats(): Map { val database = databaseHelper.readableDatabase var cursor: Cursor? = null - val result = mutableMapOf() + val result = mutableMapOf() try { cursor = database.rawQuery("select * from $publicChatTable", null) while (cursor != null && cursor.moveToNext()) { val threadID = cursor.getLong(threadID) val string = cursor.getString(publicChat) - val publicChat = PublicChat.fromJSON(string) + val publicChat = OpenGroup.fromJSON(string) if (publicChat != null) { result[threadID] = publicChat } } } catch (e: Exception) { @@ -61,16 +60,16 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa return getAllPublicChats().values.fold(setOf()) { set, chat -> set.plus(chat.server) } } - override fun getPublicChat(threadID: Long): PublicChat? { + fun getPublicChat(threadID: Long): OpenGroup? { if (threadID < 0) { return null } val database = databaseHelper.readableDatabase return database.get(publicChatTable, "${Companion.threadID} = ?", arrayOf( threadID.toString() )) { cursor -> val publicChatAsJSON = cursor.getString(publicChat) - PublicChat.fromJSON(publicChatAsJSON) + OpenGroup.fromJSON(publicChatAsJSON) } } - override fun setPublicChat(publicChat: PublicChat, threadID: Long) { + fun setPublicChat(publicChat: OpenGroup, threadID: Long) { if (threadID < 0) { return } val database = databaseHelper.writableDatabase val contentValues = ContentValues(2) @@ -79,7 +78,7 @@ class LokiThreadDatabase(context: Context, helper: SQLCipherOpenHelper) : Databa database.insertOrUpdate(publicChatTable, contentValues, "${Companion.threadID} = ?", arrayOf( threadID.toString() )) } - override fun removePublicChat(threadID: Long) { + fun removePublicChat(threadID: Long) { databaseHelper.writableDatabase.delete(publicChatTable, "${Companion.threadID} = ?", arrayOf( threadID.toString() )) } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionManagerUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionManagerUtilities.kt index f59bc7b71a..7d5503c8fc 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionManagerUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/MentionManagerUtilities.kt @@ -1,10 +1,10 @@ package org.thoughtcrime.securesms.loki.utilities import android.content.Context +import org.session.libsession.messaging.mentions.MentionsManager import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.database.model.MessageRecord import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsignal.service.loki.utilities.mentions.MentionsManager object MentionManagerUtilities { diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/OpenGroupUtilities.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/OpenGroupUtilities.kt index 9f5bad1f00..8a5f8f6bd0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/OpenGroupUtilities.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/utilities/OpenGroupUtilities.kt @@ -8,7 +8,6 @@ import org.session.libsession.messaging.open_groups.OpenGroupAPI import org.session.libsession.utilities.GroupUtil import org.session.libsession.utilities.TextSecurePreferences import org.session.libsession.utilities.preferences.ProfileKeyUtil -import org.session.libsignal.service.loki.api.opengroups.PublicChat import org.thoughtcrime.securesms.ApplicationContext import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.groups.GroupManager @@ -23,10 +22,10 @@ object OpenGroupUtilities { @Throws(Exception::class) fun addGroup(context: Context, url: String, channel: Long): OpenGroup { // Check for an existing group. - val groupID = PublicChat.getId(channel, url) + val groupID = OpenGroup.getId(channel, url) val threadID = GroupManager.getOpenGroupThreadID(groupID, context) val openGroup = DatabaseFactory.getLokiThreadDatabase(context).getPublicChat(threadID) - if (openGroup != null) { return OpenGroup.from(openGroup) } + if (openGroup != null) { return openGroup } // Add the new group. val application = ApplicationContext.getInstance(context) @@ -56,7 +55,7 @@ object OpenGroupUtilities { @Throws(Exception::class) fun updateGroupInfo(context: Context, url: String, channel: Long) { // Check if open group has a related DB record. - val groupId = GroupUtil.getEncodedOpenGroupID(PublicChat.getId(channel, url).toByteArray()) + val groupId = GroupUtil.getEncodedOpenGroupID(OpenGroup.getId(channel, url).toByteArray()) if (!DatabaseFactory.getGroupDatabase(context).hasGroup(groupId)) { throw IllegalStateException("Attempt to update open group info for non-existent DB record: $groupId") } diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt index a092841633..c731a354d2 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/views/ProfilePictureView.kt @@ -11,10 +11,10 @@ import com.bumptech.glide.load.engine.DiskCacheStrategy import kotlinx.android.synthetic.main.view_profile_picture.view.* import network.loki.messenger.R import org.session.libsession.messaging.avatars.ProfileContactPhoto +import org.session.libsession.messaging.mentions.MentionsManager import org.session.libsession.messaging.threads.Address import org.session.libsession.messaging.threads.recipients.Recipient import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsignal.service.loki.utilities.mentions.MentionsManager import org.thoughtcrime.securesms.database.DatabaseFactory import org.thoughtcrime.securesms.loki.utilities.AvatarPlaceholderGenerator import org.thoughtcrime.securesms.mms.GlideRequests From 7150374c94446c0fc4605c01a1c4f9362816964b Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 27 Apr 2021 14:26:26 +1000 Subject: [PATCH 10/13] Clean --- .../org/thoughtcrime/securesms/ApplicationContext.java | 4 ++-- .../thoughtcrime/securesms/MessageDetailsActivity.java | 4 ++-- .../thoughtcrime/securesms/components/QuoteView.java | 4 ++-- .../securesms/conversation/ConversationActivity.java | 10 +++++----- .../securesms/conversation/ConversationFragment.java | 8 ++++---- .../securesms/conversation/ConversationItem.java | 6 +++--- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index 6156e80f2f..c3fe5895a7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -33,6 +33,7 @@ import org.conscrypt.Conscrypt; import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.messaging.avatars.AvatarHelper; import org.session.libsession.messaging.jobs.JobQueue; +import org.session.libsession.messaging.mentions.MentionsManager; import org.session.libsession.messaging.open_groups.OpenGroupAPI; import org.session.libsession.messaging.sending_receiving.notifications.MessageNotifier; import org.session.libsession.messaging.sending_receiving.pollers.ClosedGroupPoller; @@ -48,7 +49,6 @@ import org.session.libsession.utilities.dynamiclanguage.LocaleParser; import org.session.libsession.utilities.preferences.ProfileKeyUtil; import org.session.libsignal.service.api.util.StreamDetails; import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol; -import org.session.libsignal.service.loki.utilities.mentions.MentionsManager; import org.session.libsignal.utilities.logging.Log; import org.signal.aesgcmprovider.AesGcmProvider; import org.thoughtcrime.securesms.components.TypingStatusSender; @@ -175,7 +175,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc new SessionProtocolImpl(this)); SnodeModule.Companion.configure(apiDB, broadcaster); if (userPublicKey != null) { - MentionsManager.Companion.configureIfNeeded(userPublicKey, threadDB, userDB); + MentionsManager.Companion.configureIfNeeded(userPublicKey, userDB); } setUpStorageAPIIfNeeded(); resubmitProfilePictureIfNeeded(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/MessageDetailsActivity.java b/app/src/main/java/org/thoughtcrime/securesms/MessageDetailsActivity.java index f78c899974..79ee15c8a7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/MessageDetailsActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/MessageDetailsActivity.java @@ -40,6 +40,7 @@ import androidx.loader.content.Loader; import org.session.libsession.messaging.messages.visible.LinkPreview; import org.session.libsession.messaging.messages.visible.Quote; import org.session.libsession.messaging.messages.visible.VisibleMessage; +import org.session.libsession.messaging.open_groups.OpenGroup; import org.session.libsession.messaging.sending_receiving.MessageSender; import org.session.libsession.messaging.sending_receiving.attachments.Attachment; import org.thoughtcrime.securesms.MessageDetailsRecipientAdapter.RecipientDeliveryStatus; @@ -64,7 +65,6 @@ import org.thoughtcrime.securesms.util.DateUtils; import org.session.libsession.utilities.ExpirationUtil; import org.session.libsession.utilities.Util; import org.session.libsignal.libsignal.util.guava.Optional; -import org.session.libsignal.service.loki.api.opengroups.PublicChat; import java.lang.ref.WeakReference; import java.sql.Date; @@ -263,7 +263,7 @@ public class MessageDetailsActivity extends PassphraseRequiredActionBarActivity } toFrom.setText(toFromRes); long threadID = messageRecord.getThreadId(); - PublicChat openGroup = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadID); + OpenGroup openGroup = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadID); if (openGroup != null && messageRecord.isOutgoing()) { toFrom.setVisibility(View.GONE); separator.setVisibility(View.GONE); diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/QuoteView.java b/app/src/main/java/org/thoughtcrime/securesms/components/QuoteView.java index 1119efaf29..5a1710875e 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/QuoteView.java +++ b/app/src/main/java/org/thoughtcrime/securesms/components/QuoteView.java @@ -21,6 +21,7 @@ import androidx.annotation.RequiresApi; import com.annimon.stream.Stream; import com.bumptech.glide.load.engine.DiskCacheStrategy; +import org.session.libsession.messaging.open_groups.OpenGroup; import org.session.libsession.messaging.sending_receiving.attachments.Attachment; import org.thoughtcrime.securesms.database.DatabaseFactory; @@ -35,7 +36,6 @@ import org.session.libsession.messaging.threads.recipients.RecipientModifiedList import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.ThemeUtil; import org.session.libsession.utilities.Util; -import org.session.libsignal.service.loki.api.opengroups.PublicChat; import java.util.List; @@ -201,7 +201,7 @@ public class QuoteView extends FrameLayout implements RecipientModifiedListener long threadID = DatabaseFactory.getThreadDatabase(getContext()).getOrCreateThreadIdFor(conversationRecipient); String senderHexEncodedPublicKey = author.getAddress().serialize(); - PublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadID); + OpenGroup publicChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadID); if (senderHexEncodedPublicKey.equalsIgnoreCase(TextSecurePreferences.getLocalNumber(getContext()))) { quoteeDisplayName = TextSecurePreferences.getProfileName(getContext()); } else if (publicChat != null) { diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java index ecc449b4f3..80a6ffb5d8 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationActivity.java @@ -85,17 +85,17 @@ import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; +import org.session.libsession.messaging.mentions.MentionsManager; import org.session.libsession.messaging.messages.control.ExpirationTimerUpdate; import org.session.libsession.messaging.messages.visible.VisibleMessage; +import org.session.libsession.messaging.open_groups.OpenGroup; import org.session.libsession.messaging.sending_receiving.attachments.Attachment; import org.session.libsession.messaging.threads.DistributionTypes; import org.session.libsession.utilities.GroupUtil; import org.session.libsession.utilities.MediaTypes; import org.session.libsignal.libsignal.InvalidMessageException; import org.session.libsignal.libsignal.util.guava.Optional; -import org.session.libsignal.service.loki.api.opengroups.PublicChat; import org.session.libsignal.service.loki.utilities.mentions.Mention; -import org.session.libsignal.service.loki.utilities.mentions.MentionsManager; import org.session.libsignal.service.loki.utilities.HexEncodingKt; import org.session.libsignal.service.loki.utilities.PublicKeyValidation; import org.thoughtcrime.securesms.ApplicationContext; @@ -376,7 +376,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity MentionManagerUtilities.INSTANCE.populateUserPublicKeyCacheIfNeeded(threadId, this); - PublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadId); + OpenGroup publicChat = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadId); if (publicChat != null) { // Request open group info update and handle the successful result in #onOpenGroupInfoUpdated(). PublicChatInfoUpdateWorker.scheduleInstant(this, publicChat.getServer(), publicChat.getChannel()); @@ -1399,7 +1399,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity @Subscribe(threadMode = ThreadMode.MAIN) public void onOpenGroupInfoUpdated(OpenGroupUtilities.GroupInfoUpdatedEvent event) { - PublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadId); + OpenGroup publicChat = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadId); if (publicChat != null && publicChat.getChannel() == event.getChannel() && publicChat.getServer().equals(event.getUrl())) { @@ -2337,7 +2337,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity muteIndicatorImageView.setVisibility(View.VISIBLE); subtitleTextView.setText("Muted until " + DateUtils.getFormattedDateTime(recipient.mutedUntil, "EEE, MMM d, yyyy HH:mm", Locale.getDefault())); } else if (recipient.isGroupRecipient() && recipient.getName() != null && !recipient.getName().equals("Session Updates") && !recipient.getName().equals("Loki News")) { - PublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadId); + OpenGroup publicChat = DatabaseFactory.getLokiThreadDatabase(this).getPublicChat(threadId); if (publicChat != null) { Integer userCount = DatabaseFactory.getLokiAPIDatabase(this).getUserCount(publicChat.getChannel(), publicChat.getServer()); if (userCount == null) { userCount = 0; } diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java index 42f8e03d5a..e78a2e16f3 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationFragment.java @@ -60,6 +60,7 @@ import com.annimon.stream.Stream; import org.session.libsession.messaging.messages.control.DataExtractionNotification; import org.session.libsession.messaging.messages.visible.Quote; import org.session.libsession.messaging.messages.visible.VisibleMessage; +import org.session.libsession.messaging.open_groups.OpenGroup; import org.session.libsession.messaging.open_groups.OpenGroupAPI; import org.thoughtcrime.securesms.ApplicationContext; import org.thoughtcrime.securesms.MessageDetailsActivity; @@ -94,7 +95,6 @@ import org.thoughtcrime.securesms.util.SaveAttachmentTask; import org.thoughtcrime.securesms.util.StickyHeaderDecoration; import org.session.libsession.utilities.task.ProgressDialogAsyncTask; import org.session.libsignal.libsignal.util.guava.Optional; -import org.session.libsignal.service.loki.api.opengroups.PublicChat; import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.Util; @@ -396,7 +396,7 @@ public class ConversationFragment extends Fragment boolean isGroupChat = recipient.isGroupRecipient(); if (isGroupChat) { - PublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadId); + OpenGroup publicChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadId); boolean isPublicChat = (publicChat != null); int selectedMessageCount = messageRecords.size(); boolean areAllSentByUser = true; @@ -508,7 +508,7 @@ public class ConversationFragment extends Fragment builder.setMessage(getActivity().getResources().getQuantityString(R.plurals.ConversationFragment_this_will_permanently_delete_all_n_selected_messages, messagesCount, messagesCount)); builder.setCancelable(true); - PublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadId); + OpenGroup publicChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadId); builder.setPositiveButton(R.string.delete, new DialogInterface.OnClickListener() { @Override @@ -591,7 +591,7 @@ public class ConversationFragment extends Fragment builder.setTitle(R.string.ConversationFragment_ban_selected_user); builder.setCancelable(true); - PublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadId); + OpenGroup publicChat = DatabaseFactory.getLokiThreadDatabase(getContext()).getPublicChat(threadId); builder.setPositiveButton(R.string.ban, (dialog, which) -> { ConversationAdapter chatAdapter = getListAdapter(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java index 6950fb5af1..6849f9cc7d 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java +++ b/app/src/main/java/org/thoughtcrime/securesms/conversation/ConversationItem.java @@ -54,6 +54,7 @@ import com.annimon.stream.Stream; import org.session.libsession.messaging.jobs.AttachmentDownloadJob; import org.session.libsession.messaging.jobs.JobQueue; +import org.session.libsession.messaging.open_groups.OpenGroup; import org.session.libsession.messaging.open_groups.OpenGroupAPI; import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress; import org.session.libsession.messaging.sending_receiving.attachments.DatabaseAttachment; @@ -67,7 +68,6 @@ import org.session.libsession.utilities.Util; import org.session.libsession.utilities.ViewUtil; import org.session.libsession.utilities.views.Stub; import org.session.libsignal.libsignal.util.guava.Optional; -import org.session.libsignal.service.loki.api.opengroups.PublicChat; import org.session.libsignal.utilities.logging.Log; import org.thoughtcrime.securesms.BindableConversationItem; import org.thoughtcrime.securesms.MediaPreviewActivity; @@ -724,7 +724,7 @@ public class ConversationItem extends LinearLayout String publicKey = recipient.getAddress().toString(); profilePictureView.setPublicKey(publicKey); String displayName = recipient.getName(); - PublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(context).getPublicChat(threadID); + OpenGroup publicChat = DatabaseFactory.getLokiThreadDatabase(context).getPublicChat(threadID); if (displayName == null && publicChat != null) { displayName = DatabaseFactory.getLokiUserDatabase(context).getServerDisplayName(publicChat.getId(), publicKey); } @@ -911,7 +911,7 @@ public class ConversationItem extends LinearLayout profilePictureView.setVisibility(VISIBLE); int visibility = View.GONE; - PublicChat publicChat = DatabaseFactory.getLokiThreadDatabase(context).getPublicChat(messageRecord.getThreadId()); + OpenGroup publicChat = DatabaseFactory.getLokiThreadDatabase(context).getPublicChat(messageRecord.getThreadId()); if (publicChat != null) { boolean isModerator = OpenGroupAPI.isUserModerator(current.getRecipient().getAddress().toString(), publicChat.getChannel(), publicChat.getServer()); visibility = isModerator ? View.VISIBLE : View.GONE; From e2ad23482d1c684aab17f063b4836f77a95c2e3b Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 27 Apr 2021 14:36:03 +1000 Subject: [PATCH 11/13] Resolve various loose ends --- .../securesms/ApplicationContext.java | 17 +++++----- .../loki/api/BackgroundPollWorker.kt | 8 ++--- .../loki/api/PushNotificationService.kt | 2 +- .../pollers/ClosedGroupPoller.kt | 2 +- .../sending_receiving/pollers/Poller.kt | 2 +- .../messaging/utilities/MessageWrapper.kt | 5 +-- .../org/session/libsession/snode/SnodeAPI.kt | 31 ++++++++++++++++--- 7 files changed, 46 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java index c3fe5895a7..e5b8b7fd5a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java +++ b/app/src/main/java/org/thoughtcrime/securesms/ApplicationContext.java @@ -32,6 +32,7 @@ import androidx.multidex.MultiDexApplication; import org.conscrypt.Conscrypt; import org.session.libsession.messaging.MessagingModuleConfiguration; import org.session.libsession.messaging.avatars.AvatarHelper; +import org.session.libsession.messaging.file_server.FileServerAPI; import org.session.libsession.messaging.jobs.JobQueue; import org.session.libsession.messaging.mentions.MentionsManager; import org.session.libsession.messaging.open_groups.OpenGroupAPI; @@ -93,6 +94,7 @@ import org.webrtc.voiceengine.WebRtcAudioUtils; import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.security.SecureRandom; import java.security.Security; import java.util.Date; import java.util.HashSet; @@ -420,7 +422,7 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc } byte[] userPrivateKey = IdentityKeyUtil.getIdentityKeyPair(this).getPrivateKey().serialize(); LokiAPIDatabaseProtocol apiDB = DatabaseFactory.getLokiAPIDatabase(this); - org.session.libsession.messaging.file_server.FileServerAPI.Companion.configure(userPublicKey, userPrivateKey, apiDB); + FileServerAPI.Companion.configure(userPublicKey, userPrivateKey, apiDB); return true; } @@ -492,13 +494,12 @@ public class ApplicationContext extends MultiDexApplication implements Dependenc try { File profilePicture = AvatarHelper.getAvatarFile(this, Address.fromSerialized(userPublicKey)); StreamDetails stream = new StreamDetails(new FileInputStream(profilePicture), "image/jpeg", profilePicture.length()); - throw new IOException(); -// FileServerAPI.uploadProfilePicture(FileServerAPI.shared.getServer(), profileKey, stream, () -> { -// TextSecurePreferences.setLastProfilePictureUpload(this, new Date().getTime()); -// TextSecurePreferences.setProfileAvatarId(this, new SecureRandom().nextInt()); -// ProfileKeyUtil.setEncodedProfileKey(this, encodedProfileKey); -// return Unit.INSTANCE; -// }); + FileServerAPI.shared.uploadProfilePicture(FileServerAPI.shared.getServer(), profileKey, stream, () -> { + TextSecurePreferences.setLastProfilePictureUpload(this, new Date().getTime()); + TextSecurePreferences.setProfileAvatarId(this, new SecureRandom().nextInt()); + ProfileKeyUtil.setEncodedProfileKey(this, encodedProfileKey); + return Unit.INSTANCE; + }); } catch (Exception exception) { // Do nothing } diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt index 9622750503..0501b0be36 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/api/BackgroundPollWorker.kt @@ -7,6 +7,7 @@ import androidx.work.* import nl.komponents.kovenant.Promise import nl.komponents.kovenant.all import nl.komponents.kovenant.functional.map +import org.session.libsession.messaging.jobs.MessageReceiveJob import org.session.libsession.messaging.open_groups.OpenGroup import org.session.libsession.messaging.sending_receiving.pollers.OpenGroupPoller import org.session.libsession.snode.SnodeAPI @@ -71,10 +72,9 @@ class BackgroundPollWorker(val context: Context, params: WorkerParameters) : Wor // Private chats val userPublicKey = TextSecurePreferences.getLocalNumber(context)!! val privateChatsPromise = SnodeAPI.getMessages(userPublicKey).map { envelopes -> - throw IOException() -// envelopes.map { envelope -> -// MessageReceiveJob(envelope.toByteArray(), false).executeAsync() -// } + envelopes.map { envelope -> + MessageReceiveJob(envelope.toByteArray(), false).executeAsync() + } } promises.addAll(privateChatsPromise.get()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/loki/api/PushNotificationService.kt b/app/src/main/java/org/thoughtcrime/securesms/loki/api/PushNotificationService.kt index 5e5305103a..ebe9baf29c 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/loki/api/PushNotificationService.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/loki/api/PushNotificationService.kt @@ -27,7 +27,7 @@ class PushNotificationService : FirebaseMessagingService() { val data = base64EncodedData?.let { Base64.decode(it) } if (data != null) { try { - JobQueue.shared.add(MessageReceiveJob(MessageWrapper.unwrap(data),true)) + JobQueue.shared.add(MessageReceiveJob(MessageWrapper.unwrap(data).toByteArray(),true)) } catch (e: Exception) { Log.d("Loki", "Failed to unwrap data for message due to error: $e.") } diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/ClosedGroupPoller.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/ClosedGroupPoller.kt index e6d68911d3..3c1b6de032 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/ClosedGroupPoller.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/ClosedGroupPoller.kt @@ -78,7 +78,7 @@ class ClosedGroupPoller { val rawMessageAsJSON = message as? Map<*, *> val base64EncodedData = rawMessageAsJSON?.get("data") as? String val data = base64EncodedData?.let { Base64.decode(it) } ?: return@forEach - val job = MessageReceiveJob(MessageWrapper.unwrap(data), false) + val job = MessageReceiveJob(MessageWrapper.unwrap(data).toByteArray(), false) JobQueue.shared.add(job) } } diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt index cbbb1b831c..5a862d89af 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt @@ -97,7 +97,7 @@ class Poller { val rawMessageAsJSON = message as? Map<*, *> val base64EncodedData = rawMessageAsJSON?.get("data") as? String val data = base64EncodedData?.let { Base64.decode(it) } ?: return@forEach - val job = MessageReceiveJob(MessageWrapper.unwrap(data), false) + val job = MessageReceiveJob(MessageWrapper.unwrap(data).toByteArray(), false) JobQueue.shared.add(job) } poll(snode, deferred) diff --git a/libsession/src/main/java/org/session/libsession/messaging/utilities/MessageWrapper.kt b/libsession/src/main/java/org/session/libsession/messaging/utilities/MessageWrapper.kt index b11cbe1774..767e4beffe 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/utilities/MessageWrapper.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/utilities/MessageWrapper.kt @@ -1,6 +1,7 @@ package org.session.libsession.messaging.utilities import com.google.protobuf.ByteString +import org.session.libsignal.metadata.SignalProtos import org.session.libsignal.utilities.logging.Log import org.session.libsignal.service.internal.push.SignalServiceProtos.Envelope import org.session.libsignal.service.internal.websocket.WebSocketProtos.WebSocketMessage @@ -69,11 +70,11 @@ object MessageWrapper { /** * `data` shouldn't be base 64 encoded. */ - fun unwrap(data: ByteArray): ByteArray { + fun unwrap(data: ByteArray): Envelope { try { val webSocketMessage = WebSocketMessage.parseFrom(data) val envelopeAsData = webSocketMessage.request.body - return envelopeAsData.toByteArray() + return Envelope.parseFrom(envelopeAsData); } catch (e: Exception) { Log.d("Loki", "Failed to unwrap data: ${e.message}.") throw Error.FailedToUnwrapData diff --git a/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt b/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt index 5a0baa90b5..afb3050d99 100644 --- a/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt +++ b/libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt @@ -6,7 +6,9 @@ import android.os.Build import nl.komponents.kovenant.* import nl.komponents.kovenant.functional.bind import nl.komponents.kovenant.functional.map +import org.session.libsession.messaging.utilities.MessageWrapper import org.session.libsession.snode.utilities.getRandomElement +import org.session.libsignal.service.internal.push.SignalServiceProtos import org.session.libsignal.service.loki.Snode import org.session.libsignal.service.loki.api.utilities.HTTP import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol @@ -226,13 +228,14 @@ object SnodeAPI { } } - fun parseRawMessagesResponse(rawResponse: RawResponse, snode: Snode, publicKey: String): List<*> { + fun parseRawMessagesResponse(rawResponse: RawResponse, snode: Snode, publicKey: String): List { val messages = rawResponse["messages"] as? List<*> return if (messages != null) { updateLastMessageHashValueIfPossible(snode, publicKey, messages) - removeDuplicates(publicKey, messages) + val newRawMessages = removeDuplicates(publicKey, messages) + return parseEnvelopes(newRawMessages); } else { - listOf>() + listOf() } } @@ -263,6 +266,26 @@ object SnodeAPI { } } + private fun parseEnvelopes(rawMessages: List<*>): List { + return rawMessages.mapNotNull { rawMessage -> + val rawMessageAsJSON = rawMessage as? Map<*, *> + val base64EncodedData = rawMessageAsJSON?.get("data") as? String + val data = base64EncodedData?.let { Base64.decode(it) } + if (data != null) { + try { + MessageWrapper.unwrap(data) + } catch (e: Exception) { + Log.d("Loki", "Failed to unwrap data for message: ${rawMessage.prettifiedDescription()}.") + null + } + } else { + Log.d("Loki", "Failed to decode data for message: ${rawMessage?.prettifiedDescription()}.") + null + } + } + } + // endregion + // Error Handling internal fun handleSnodeError(statusCode: Int, json: Map<*, *>?, snode: Snode, publicKey: String? = null): Exception? { fun handleBadSnode() { @@ -310,5 +333,5 @@ object SnodeAPI { // Type Aliases typealias RawResponse = Map<*, *> -typealias MessageListPromise = Promise, Exception> +typealias MessageListPromise = Promise, Exception> typealias RawResponsePromise = Promise From a14fc0503f448b6989cc49cd4cbc1edf5df74ad3 Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 27 Apr 2021 14:48:57 +1000 Subject: [PATCH 12/13] Take care of remaining loose ends --- .../securesms/jobs/AvatarDownloadJob.java | 20 ++++- .../jobs/RetrieveProfileAvatarJob.java | 6 +- .../messaging/open_groups/OpenGroupAPI.kt | 4 +- .../libsession/utilities/DownloadUtilities.kt | 88 +++++++++++++++++++ 4 files changed, 113 insertions(+), 5 deletions(-) create mode 100644 libsession/src/main/java/org/session/libsession/utilities/DownloadUtilities.kt diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/AvatarDownloadJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/AvatarDownloadJob.java index b31029c354..34faaf48a4 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/AvatarDownloadJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/AvatarDownloadJob.java @@ -4,6 +4,8 @@ import android.graphics.Bitmap; import androidx.annotation.NonNull; import org.session.libsession.messaging.jobs.Data; +import org.session.libsession.utilities.DownloadUtilities; +import org.session.libsignal.service.api.crypto.AttachmentCipherInputStream; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.session.libsession.messaging.threads.GroupRecord; @@ -22,6 +24,7 @@ import org.session.libsignal.service.api.messages.SignalServiceAttachmentPointer import org.session.libsignal.service.api.push.exceptions.NonSuccessfulResponseCodeException; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; @@ -91,9 +94,20 @@ public class AvatarDownloadJob extends BaseJob implements InjectableType { attachment = File.createTempFile("avatar", "tmp", context.getCacheDir()); attachment.deleteOnExit(); - SignalServiceAttachmentPointer pointer = new SignalServiceAttachmentPointer(avatarId, contentType, key, Optional.of(0), Optional.absent(), 0, 0, digest, fileName, false, Optional.absent(), url); - InputStream inputStream = receiver.retrieveAttachment(pointer, attachment, MAX_AVATAR_SIZE); - Bitmap avatar = BitmapUtil.createScaledBitmap(context, new AttachmentModel(attachment, key, 0, digest), 500, 500); + SignalServiceAttachmentPointer pointer = new SignalServiceAttachmentPointer(avatarId, contentType, key, Optional.of(0), Optional.absent(), 0, 0, digest, fileName, false, Optional.absent(), url); + + if (pointer.getUrl().isEmpty()) throw new InvalidMessageException("Missing attachment URL."); + DownloadUtilities.downloadFile(attachment, pointer.getUrl(), MAX_AVATAR_SIZE, null); + + // Assume we're retrieving an attachment for an open group server if the digest is not set + InputStream inputStream; + if (!pointer.getDigest().isPresent()) { + inputStream = new FileInputStream(attachment); + } else { + inputStream = AttachmentCipherInputStream.createForAttachment(attachment, pointer.getSize().or(0), pointer.getKey(), pointer.getDigest().get()); + } + + Bitmap avatar = BitmapUtil.createScaledBitmap(context, new AttachmentModel(attachment, key, 0, digest), 500, 500); database.updateProfilePicture(groupId, avatar); inputStream.close(); diff --git a/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.java b/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.java index d89db00604..8211032292 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.java +++ b/app/src/main/java/org/thoughtcrime/securesms/jobs/RetrieveProfileAvatarJob.java @@ -10,9 +10,11 @@ import org.session.libsession.messaging.avatars.AvatarHelper; import org.session.libsession.messaging.jobs.Data; import org.session.libsession.messaging.threads.Address; import org.session.libsession.messaging.threads.recipients.Recipient; +import org.session.libsession.utilities.DownloadUtilities; import org.session.libsession.utilities.TextSecurePreferences; import org.session.libsession.utilities.Util; import org.session.libsignal.service.api.SignalServiceMessageReceiver; +import org.session.libsignal.service.api.crypto.ProfileCipherInputStream; import org.session.libsignal.service.api.push.exceptions.PushNetworkException; import org.session.libsignal.utilities.logging.Log; import org.thoughtcrime.securesms.database.DatabaseFactory; @@ -22,6 +24,7 @@ import org.thoughtcrime.securesms.jobmanager.Job; import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; @@ -102,7 +105,8 @@ public class RetrieveProfileAvatarJob extends BaseJob implements InjectableType File downloadDestination = File.createTempFile("avatar", ".jpg", context.getCacheDir()); try { - InputStream avatarStream = receiver.retrieveProfileAvatar(profileAvatar, downloadDestination, profileKey, MAX_PROFILE_SIZE_BYTES); + DownloadUtilities.downloadFile(downloadDestination, profileAvatar, MAX_PROFILE_SIZE_BYTES, null); + InputStream avatarStream = new ProfileCipherInputStream(new FileInputStream(downloadDestination), profileKey); File decryptDestination = File.createTempFile("avatar", ".jpg", context.getCacheDir()); Util.copy(avatarStream, new FileOutputStream(decryptDestination)); diff --git a/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPI.kt b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPI.kt index 211bf33643..bd70118abd 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPI.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/open_groups/OpenGroupAPI.kt @@ -6,7 +6,9 @@ import nl.komponents.kovenant.deferred import nl.komponents.kovenant.functional.map import nl.komponents.kovenant.then import org.session.libsession.messaging.MessagingModuleConfiguration +import org.session.libsession.messaging.file_server.FileServerAPI import org.session.libsession.messaging.utilities.DotNetAPI +import org.session.libsession.utilities.DownloadUtilities import org.session.libsignal.service.loki.utilities.retryIfNeeded import org.session.libsignal.utilities.* import org.session.libsignal.utilities.Base64 @@ -315,7 +317,7 @@ object OpenGroupAPI: DotNetAPI() { Log.d("Loki", "Downloading open group profile picture from \"$url\".") val outputStream = ByteArrayOutputStream() try { - throw IOException(); + DownloadUtilities.downloadFile(outputStream, url, FileServerAPI.maxFileSize, null) Log.d("Loki", "Open group profile picture was successfully loaded from \"$url\"") return outputStream.toByteArray() } catch (e: Exception) { diff --git a/libsession/src/main/java/org/session/libsession/utilities/DownloadUtilities.kt b/libsession/src/main/java/org/session/libsession/utilities/DownloadUtilities.kt new file mode 100644 index 0000000000..1c0e29f045 --- /dev/null +++ b/libsession/src/main/java/org/session/libsession/utilities/DownloadUtilities.kt @@ -0,0 +1,88 @@ +package org.session.libsession.utilities + +import okhttp3.HttpUrl +import okhttp3.Request +import org.session.libsession.messaging.file_server.FileServerAPI +import org.session.libsession.snode.OnionRequestAPI +import org.session.libsignal.utilities.logging.Log +import org.session.libsignal.service.api.messages.SignalServiceAttachment +import org.session.libsignal.service.api.push.exceptions.NonSuccessfulResponseCodeException +import org.session.libsignal.service.api.push.exceptions.PushNetworkException +import org.session.libsignal.utilities.Base64 +import java.io.* + +object DownloadUtilities { + + /** + * Blocks the calling thread. + */ + @JvmStatic + fun downloadFile(destination: File, url: String, maxSize: Int, listener: SignalServiceAttachment.ProgressListener?) { + val outputStream = FileOutputStream(destination) // Throws + var remainingAttempts = 4 + var exception: Exception? = null + while (remainingAttempts > 0) { + remainingAttempts -= 1 + try { + downloadFile(outputStream, url, maxSize, listener) + exception = null + break + } catch (e: Exception) { + exception = e + } + } + if (exception != null) { throw exception } + } + + /** + * Blocks the calling thread. + */ + @JvmStatic + fun downloadFile(outputStream: OutputStream, url: String, maxSize: Int, listener: SignalServiceAttachment.ProgressListener?) { + // We need to throw a PushNetworkException or NonSuccessfulResponseCodeException + // because the underlying Signal logic requires these to work correctly + val oldPrefixedHost = "https://" + HttpUrl.get(url).host() + var newPrefixedHost = oldPrefixedHost + if (oldPrefixedHost.contains(FileServerAPI.fileStorageBucketURL)) { + newPrefixedHost = FileServerAPI.shared.server + } + // Edge case that needs to work: https://file-static.lokinet.org/i1pNmpInq3w9gF3TP8TFCa1rSo38J6UM + // → https://file.getsession.org/loki/v1/f/XLxogNXVEIWHk14NVCDeppzTujPHxu35 + val fileID = url.substringAfter(oldPrefixedHost).substringAfter("/f/") + val sanitizedURL = "$newPrefixedHost/loki/v1/f/$fileID" + val request = Request.Builder().url(sanitizedURL).get() + try { + val serverPublicKey = if (newPrefixedHost.contains(FileServerAPI.shared.server)) FileServerAPI.fileServerPublicKey + else FileServerAPI.shared.getPublicKeyForOpenGroupServer(newPrefixedHost).get() + val json = OnionRequestAPI.sendOnionRequest(request.build(), newPrefixedHost, serverPublicKey, isJSONRequired = false).get() + val result = json["result"] as? String + if (result == null) { + Log.d("Loki", "Couldn't parse attachment from: $json.") + throw PushNetworkException("Missing response body.") + } + val body = Base64.decode(result) + if (body.size > maxSize) { + Log.d("Loki", "Attachment size limit exceeded.") + throw PushNetworkException("Max response size exceeded.") + } + body.inputStream().use { input -> + val buffer = ByteArray(32768) + var count = 0 + var bytes = input.read(buffer) + while (bytes >= 0) { + outputStream.write(buffer, 0, bytes) + count += bytes + if (count > maxSize) { + Log.d("Loki", "Attachment size limit exceeded.") + throw PushNetworkException("Max response size exceeded.") + } + listener?.onAttachmentProgress(body.size.toLong(), count.toLong()) + bytes = input.read(buffer) + } + } + } catch (e: Exception) { + Log.d("Loki", "Couldn't download attachment due to error: $e.") + throw if (e is NonSuccessfulResponseCodeException) e else PushNetworkException(e) + } + } +} \ No newline at end of file From 97c74bb3dcbfc7a246b1e4edf012f21523927dc6 Mon Sep 17 00:00:00 2001 From: nielsandriesse Date: Wed, 28 Apr 2021 14:10:44 +1000 Subject: [PATCH 13/13] Fix polling --- .../messaging/sending_receiving/pollers/Poller.kt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt index 5a862d89af..e2754b4090 100644 --- a/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt +++ b/libsession/src/main/java/org/session/libsession/messaging/sending_receiving/pollers/Poller.kt @@ -93,11 +93,8 @@ class Poller { task { Unit } // The long polling connection has been canceled; don't recurse } else { val messages = SnodeAPI.parseRawMessagesResponse(rawResponse, snode, userPublicKey) - messages.forEach { message -> - val rawMessageAsJSON = message as? Map<*, *> - val base64EncodedData = rawMessageAsJSON?.get("data") as? String - val data = base64EncodedData?.let { Base64.decode(it) } ?: return@forEach - val job = MessageReceiveJob(MessageWrapper.unwrap(data).toByteArray(), false) + messages.forEach { envelope -> + val job = MessageReceiveJob(envelope.toByteArray(), false) JobQueue.shared.add(job) } poll(snode, deferred)