mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-23 18:15:22 +00:00
refactor: performance improvements in batch message processing, synchronized cache access and audible message notifications.
Increase audible timeout on DefaultMessageNotifier.java, don't send in-thread notification based on last audible notification. Create a batch message receive job to handle up to 20 chunked messages at a time per job instead of singular or open group poll amount Remove synchronized access to recipient cache and replace with a concurrent cache that's lock free from perf tracing monitor contention
This commit is contained in:
parent
5a290ddf68
commit
e036344c76
@ -97,7 +97,7 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
|||||||
private static final int SUMMARY_NOTIFICATION_ID = 1338;
|
private static final int SUMMARY_NOTIFICATION_ID = 1338;
|
||||||
private static final int PENDING_MESSAGES_ID = 1111;
|
private static final int PENDING_MESSAGES_ID = 1111;
|
||||||
private static final String NOTIFICATION_GROUP = "messages";
|
private static final String NOTIFICATION_GROUP = "messages";
|
||||||
private static final long MIN_AUDIBLE_PERIOD_MILLIS = TimeUnit.SECONDS.toMillis(2);
|
private static final long MIN_AUDIBLE_PERIOD_MILLIS = TimeUnit.SECONDS.toMillis(5);
|
||||||
private static final long DESKTOP_ACTIVITY_PERIOD = TimeUnit.MINUTES.toMillis(1);
|
private static final long DESKTOP_ACTIVITY_PERIOD = TimeUnit.MINUTES.toMillis(1);
|
||||||
|
|
||||||
private volatile static long visibleThread = -1;
|
private volatile static long visibleThread = -1;
|
||||||
@ -440,9 +440,12 @@ public class DefaultMessageNotifier implements MessageNotifier {
|
|||||||
|
|
||||||
private void sendInThreadNotification(Context context, Recipient recipient) {
|
private void sendInThreadNotification(Context context, Recipient recipient) {
|
||||||
if (!TextSecurePreferences.isInThreadNotifications(context) ||
|
if (!TextSecurePreferences.isInThreadNotifications(context) ||
|
||||||
ServiceUtil.getAudioManager(context).getRingerMode() != AudioManager.RINGER_MODE_NORMAL)
|
ServiceUtil.getAudioManager(context).getRingerMode() != AudioManager.RINGER_MODE_NORMAL ||
|
||||||
|
(System.currentTimeMillis() - lastAudibleNotification) < MIN_AUDIBLE_PERIOD_MILLIS)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
} else {
|
||||||
|
lastAudibleNotification = System.currentTimeMillis();
|
||||||
}
|
}
|
||||||
|
|
||||||
Uri uri = null;
|
Uri uri = null;
|
||||||
|
@ -5,7 +5,6 @@ import android.net.Uri
|
|||||||
import org.session.libsession.messaging.contacts.Contact
|
import org.session.libsession.messaging.contacts.Contact
|
||||||
import org.session.libsession.messaging.jobs.AttachmentUploadJob
|
import org.session.libsession.messaging.jobs.AttachmentUploadJob
|
||||||
import org.session.libsession.messaging.jobs.Job
|
import org.session.libsession.messaging.jobs.Job
|
||||||
import org.session.libsession.messaging.jobs.MessageReceiveJob
|
|
||||||
import org.session.libsession.messaging.jobs.MessageSendJob
|
import org.session.libsession.messaging.jobs.MessageSendJob
|
||||||
import org.session.libsession.messaging.messages.control.ConfigurationMessage
|
import org.session.libsession.messaging.messages.control.ConfigurationMessage
|
||||||
import org.session.libsession.messaging.messages.visible.Attachment
|
import org.session.libsession.messaging.messages.visible.Attachment
|
||||||
@ -43,7 +42,7 @@ interface StorageProtocol {
|
|||||||
fun getAllPendingJobs(type: String): Map<String,Job?>
|
fun getAllPendingJobs(type: String): Map<String,Job?>
|
||||||
fun getAttachmentUploadJob(attachmentID: Long): AttachmentUploadJob?
|
fun getAttachmentUploadJob(attachmentID: Long): AttachmentUploadJob?
|
||||||
fun getMessageSendJob(messageSendJobID: String): MessageSendJob?
|
fun getMessageSendJob(messageSendJobID: String): MessageSendJob?
|
||||||
fun getMessageReceiveJob(messageReceiveJobID: String): MessageReceiveJob?
|
fun getMessageReceiveJob(messageReceiveJobID: String): Job?
|
||||||
fun resumeMessageSendJobIfNeeded(messageSendJobID: String)
|
fun resumeMessageSendJobIfNeeded(messageSendJobID: String)
|
||||||
fun isJobCanceled(job: Job): Boolean
|
fun isJobCanceled(job: Job): Boolean
|
||||||
|
|
||||||
|
@ -0,0 +1,120 @@
|
|||||||
|
package org.session.libsession.messaging.jobs
|
||||||
|
|
||||||
|
import com.google.protobuf.ByteString
|
||||||
|
import nl.komponents.kovenant.Promise
|
||||||
|
import nl.komponents.kovenant.task
|
||||||
|
import org.session.libsession.messaging.sending_receiving.MessageReceiver
|
||||||
|
import org.session.libsession.messaging.sending_receiving.handle
|
||||||
|
import org.session.libsession.messaging.utilities.Data
|
||||||
|
import org.session.libsignal.protos.UtilProtos
|
||||||
|
import org.session.libsignal.utilities.Log
|
||||||
|
|
||||||
|
data class MessageReceiveParameters(
|
||||||
|
val data: ByteArray,
|
||||||
|
val serverHash: String? = null,
|
||||||
|
val openGroupMessageServerID: Long? = null
|
||||||
|
)
|
||||||
|
|
||||||
|
class BatchMessageReceiveJob(
|
||||||
|
val messages: List<MessageReceiveParameters>,
|
||||||
|
val openGroupID: String? = null
|
||||||
|
) : Job {
|
||||||
|
|
||||||
|
override var delegate: JobDelegate? = null
|
||||||
|
override var id: String? = null
|
||||||
|
override var failureCount: Int = 0
|
||||||
|
override val maxFailureCount: Int = 10
|
||||||
|
// Failure Exceptions must be retryable if they're a MessageReceiver.Error
|
||||||
|
val failures = mutableListOf<MessageReceiveParameters>()
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val TAG = "BatchMessageReceiveJob"
|
||||||
|
const val KEY = "BatchMessageReceiveJob"
|
||||||
|
|
||||||
|
// Keys used for database storage
|
||||||
|
private val NUM_MESSAGES_KEY = "numMessages"
|
||||||
|
private val DATA_KEY = "data"
|
||||||
|
private val SERVER_HASH_KEY = "serverHash"
|
||||||
|
private val OPEN_GROUP_MESSAGE_SERVER_ID_KEY = "openGroupMessageServerID"
|
||||||
|
private val OPEN_GROUP_ID_KEY = "open_group_id"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun execute() {
|
||||||
|
executeAsync().get()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun executeAsync(): Promise<Unit, Exception> {
|
||||||
|
return task {
|
||||||
|
messages.forEach { messageParameters ->
|
||||||
|
val (data, serverHash, openGroupMessageServerID) = messageParameters
|
||||||
|
try {
|
||||||
|
val (message, proto) = MessageReceiver.parse(data, openGroupMessageServerID)
|
||||||
|
message.serverHash = serverHash
|
||||||
|
MessageReceiver.handle(message, proto, this.openGroupID)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "Couldn't receive message.", e)
|
||||||
|
if (e is MessageReceiver.Error && !e.isRetryable) {
|
||||||
|
Log.e(TAG, "Message failed permanently",e)
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "Message failed",e)
|
||||||
|
failures += messageParameters
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (failures.isEmpty()) {
|
||||||
|
handleSuccess()
|
||||||
|
} else {
|
||||||
|
handleFailure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleSuccess() {
|
||||||
|
this.delegate?.handleJobSucceeded(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleFailure() {
|
||||||
|
this.delegate?.handleJobFailed(this, Exception("One or more jobs resulted in failure"))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun serialize(): Data {
|
||||||
|
val arraySize = messages.size
|
||||||
|
val dataArrays = UtilProtos.ByteArrayList.newBuilder()
|
||||||
|
.addAllContent(messages.map(MessageReceiveParameters::data).map(ByteString::copyFrom))
|
||||||
|
.build()
|
||||||
|
val serverHashes = messages.map { it.serverHash.orEmpty() }
|
||||||
|
val openGroupServerIds = messages.map { it.openGroupMessageServerID ?: -1L }
|
||||||
|
return Data.Builder()
|
||||||
|
.putInt(NUM_MESSAGES_KEY, arraySize)
|
||||||
|
.putByteArray(DATA_KEY, dataArrays.toByteArray())
|
||||||
|
.putString(OPEN_GROUP_ID_KEY, openGroupID)
|
||||||
|
.putLongArray(OPEN_GROUP_MESSAGE_SERVER_ID_KEY, openGroupServerIds.toLongArray())
|
||||||
|
.putStringArray(SERVER_HASH_KEY, serverHashes.toTypedArray())
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFactoryKey(): String = KEY
|
||||||
|
|
||||||
|
class Factory : Job.Factory<BatchMessageReceiveJob> {
|
||||||
|
override fun create(data: Data): BatchMessageReceiveJob {
|
||||||
|
val numMessages = data.getInt(NUM_MESSAGES_KEY)
|
||||||
|
val dataArrays = data.getByteArray(DATA_KEY)
|
||||||
|
val contents =
|
||||||
|
UtilProtos.ByteArrayList.parseFrom(dataArrays).contentList.map(ByteString::toByteArray)
|
||||||
|
val serverHashes =
|
||||||
|
if (data.hasStringArray(SERVER_HASH_KEY)) data.getStringArray(SERVER_HASH_KEY) else arrayOf()
|
||||||
|
val openGroupMessageServerIDs = data.getLongArray(OPEN_GROUP_MESSAGE_SERVER_ID_KEY)
|
||||||
|
val openGroupID = data.getStringOrDefault(OPEN_GROUP_ID_KEY, null)
|
||||||
|
|
||||||
|
val parameters = (0 until numMessages).map { index ->
|
||||||
|
val data = contents[index]
|
||||||
|
val serverHash = serverHashes[index].let { if (it.isEmpty()) null else it }
|
||||||
|
val serverId = openGroupMessageServerIDs[index].let { if (it == -1L) null else it }
|
||||||
|
MessageReceiveParameters(data, serverHash, serverId)
|
||||||
|
}
|
||||||
|
|
||||||
|
return BatchMessageReceiveJob(parameters, openGroupID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -5,7 +5,6 @@ import kotlinx.coroutines.channels.Channel
|
|||||||
import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED
|
import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED
|
||||||
import org.session.libsession.messaging.MessagingModuleConfiguration
|
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||||
import org.session.libsignal.utilities.Log
|
import org.session.libsignal.utilities.Log
|
||||||
import java.lang.IllegalStateException
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
@ -51,7 +50,7 @@ class JobQueue : JobDelegate {
|
|||||||
when (job) {
|
when (job) {
|
||||||
is NotifyPNServerJob, is AttachmentUploadJob, is MessageSendJob -> txQueue.send(job)
|
is NotifyPNServerJob, is AttachmentUploadJob, is MessageSendJob -> txQueue.send(job)
|
||||||
is AttachmentDownloadJob -> attachmentQueue.send(job)
|
is AttachmentDownloadJob -> attachmentQueue.send(job)
|
||||||
is MessageReceiveJob, is TrimThreadJob -> rxQueue.send(job)
|
is MessageReceiveJob, is BatchMessageReceiveJob, is TrimThreadJob -> rxQueue.send(job)
|
||||||
else -> throw IllegalStateException("Unexpected job type.")
|
else -> throw IllegalStateException("Unexpected job type.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,7 +127,8 @@ class JobQueue : JobDelegate {
|
|||||||
AttachmentDownloadJob.KEY,
|
AttachmentDownloadJob.KEY,
|
||||||
MessageReceiveJob.KEY,
|
MessageReceiveJob.KEY,
|
||||||
MessageSendJob.KEY,
|
MessageSendJob.KEY,
|
||||||
NotifyPNServerJob.KEY
|
NotifyPNServerJob.KEY,
|
||||||
|
BatchMessageReceiveJob.KEY
|
||||||
)
|
)
|
||||||
allJobTypes.forEach { type ->
|
allJobTypes.forEach { type ->
|
||||||
resumePendingJobs(type)
|
resumePendingJobs(type)
|
||||||
@ -152,6 +152,11 @@ class JobQueue : JobDelegate {
|
|||||||
Log.i("Loki", "Message send job waiting for attachment upload to finish.")
|
Log.i("Loki", "Message send job waiting for attachment upload to finish.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// Batch message receive job, re-queue non-permanently failed jobs
|
||||||
|
if (job is BatchMessageReceiveJob) {
|
||||||
|
val replacementParameters = job.failures
|
||||||
|
}
|
||||||
|
|
||||||
// Regular job failure
|
// Regular job failure
|
||||||
job.failureCount += 1
|
job.failureCount += 1
|
||||||
if (job.failureCount >= job.maxFailureCount) {
|
if (job.failureCount >= job.maxFailureCount) {
|
||||||
|
@ -17,8 +17,6 @@ class MessageReceiveJob(val data: ByteArray, val serverHash: String? = null, val
|
|||||||
val TAG = MessageReceiveJob::class.simpleName
|
val TAG = MessageReceiveJob::class.simpleName
|
||||||
val KEY: String = "MessageReceiveJob"
|
val KEY: String = "MessageReceiveJob"
|
||||||
|
|
||||||
private val RECEIVE_LOCK = Object()
|
|
||||||
|
|
||||||
// Keys used for database storage
|
// Keys used for database storage
|
||||||
private val DATA_KEY = "data"
|
private val DATA_KEY = "data"
|
||||||
private val SERVER_HASH_KEY = "serverHash"
|
private val SERVER_HASH_KEY = "serverHash"
|
||||||
@ -36,9 +34,7 @@ class MessageReceiveJob(val data: ByteArray, val serverHash: String? = null, val
|
|||||||
val isRetry: Boolean = failureCount != 0
|
val isRetry: Boolean = failureCount != 0
|
||||||
val (message, proto) = MessageReceiver.parse(this.data, this.openGroupMessageServerID)
|
val (message, proto) = MessageReceiver.parse(this.data, this.openGroupMessageServerID)
|
||||||
message.serverHash = serverHash
|
message.serverHash = serverHash
|
||||||
synchronized(RECEIVE_LOCK) { // FIXME: Do we need this?
|
MessageReceiver.handle(message, proto, this.openGroupID)
|
||||||
MessageReceiver.handle(message, proto, this.openGroupID)
|
|
||||||
}
|
|
||||||
this.handleSuccess()
|
this.handleSuccess()
|
||||||
deferred.resolve(Unit)
|
deferred.resolve(Unit)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
@ -82,11 +78,15 @@ class MessageReceiveJob(val data: ByteArray, val serverHash: String? = null, val
|
|||||||
class Factory: Job.Factory<MessageReceiveJob> {
|
class Factory: Job.Factory<MessageReceiveJob> {
|
||||||
|
|
||||||
override fun create(data: Data): MessageReceiveJob {
|
override fun create(data: Data): MessageReceiveJob {
|
||||||
|
val dataArray = data.getByteArray(DATA_KEY)
|
||||||
|
val serverHash = data.getStringOrDefault(SERVER_HASH_KEY, null)
|
||||||
|
val openGroupMessageServerID = data.getLongOrDefault(OPEN_GROUP_MESSAGE_SERVER_ID_KEY, -1).let { if (it == -1L) null else it }
|
||||||
|
val openGroupID = data.getStringOrDefault(OPEN_GROUP_ID_KEY, null)
|
||||||
return MessageReceiveJob(
|
return MessageReceiveJob(
|
||||||
data.getByteArray(DATA_KEY),
|
dataArray,
|
||||||
data.getString(SERVER_HASH_KEY),
|
serverHash,
|
||||||
data.getLong(OPEN_GROUP_MESSAGE_SERVER_ID_KEY),
|
openGroupMessageServerID,
|
||||||
data.getString(OPEN_GROUP_ID_KEY)
|
openGroupID
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,8 @@ class SessionJobManagerFactories {
|
|||||||
MessageReceiveJob.KEY to MessageReceiveJob.Factory(),
|
MessageReceiveJob.KEY to MessageReceiveJob.Factory(),
|
||||||
MessageSendJob.KEY to MessageSendJob.Factory(),
|
MessageSendJob.KEY to MessageSendJob.Factory(),
|
||||||
NotifyPNServerJob.KEY to NotifyPNServerJob.Factory(),
|
NotifyPNServerJob.KEY to NotifyPNServerJob.Factory(),
|
||||||
TrimThreadJob.KEY to TrimThreadJob.Factory()
|
TrimThreadJob.KEY to TrimThreadJob.Factory(),
|
||||||
|
BatchMessageReceiveJob.KEY to BatchMessageReceiveJob.Factory()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,17 +3,12 @@ package org.session.libsession.messaging.sending_receiving.pollers
|
|||||||
import nl.komponents.kovenant.Promise
|
import nl.komponents.kovenant.Promise
|
||||||
import nl.komponents.kovenant.functional.map
|
import nl.komponents.kovenant.functional.map
|
||||||
import org.session.libsession.messaging.MessagingModuleConfiguration
|
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||||
import org.session.libsession.messaging.jobs.JobQueue
|
import org.session.libsession.messaging.jobs.*
|
||||||
import org.session.libsession.messaging.jobs.MessageReceiveJob
|
|
||||||
import org.session.libsession.messaging.jobs.TrimThreadJob
|
|
||||||
import org.session.libsession.messaging.open_groups.OpenGroupAPIV2
|
import org.session.libsession.messaging.open_groups.OpenGroupAPIV2
|
||||||
import org.session.libsession.messaging.open_groups.OpenGroupMessageV2
|
import org.session.libsession.messaging.open_groups.OpenGroupMessageV2
|
||||||
import org.session.libsession.messaging.sending_receiving.MessageReceiver
|
|
||||||
import org.session.libsession.messaging.sending_receiving.handle
|
|
||||||
import org.session.libsession.utilities.Address
|
import org.session.libsession.utilities.Address
|
||||||
import org.session.libsession.utilities.GroupUtil
|
import org.session.libsession.utilities.GroupUtil
|
||||||
import org.session.libsignal.protos.SignalServiceProtos
|
import org.session.libsignal.protos.SignalServiceProtos
|
||||||
import org.session.libsignal.utilities.Log
|
|
||||||
import org.session.libsignal.utilities.successBackground
|
import org.session.libsignal.utilities.successBackground
|
||||||
import java.util.concurrent.ScheduledExecutorService
|
import java.util.concurrent.ScheduledExecutorService
|
||||||
import java.util.concurrent.ScheduledFuture
|
import java.util.concurrent.ScheduledFuture
|
||||||
@ -27,7 +22,7 @@ class OpenGroupPollerV2(private val server: String, private val executorService:
|
|||||||
private var future: ScheduledFuture<*>? = null
|
private var future: ScheduledFuture<*>? = null
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val pollInterval: Long = 4 * 1000
|
private const val pollInterval: Long = 4000L
|
||||||
const val maxInactivityPeriod = 14 * 24 * 60 * 60 * 1000
|
const val maxInactivityPeriod = 14 * 24 * 60 * 60 * 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,21 +61,22 @@ class OpenGroupPollerV2(private val server: String, private val executorService:
|
|||||||
val threadId = storage.getThreadId(Address.fromSerialized(groupID)) ?: -1
|
val threadId = storage.getThreadId(Address.fromSerialized(groupID)) ?: -1
|
||||||
val threadExists = threadId >= 0
|
val threadExists = threadId >= 0
|
||||||
if (!hasStarted || !threadExists) { return }
|
if (!hasStarted || !threadExists) { return }
|
||||||
messages.sortedBy { it.serverID!! }.forEach { message ->
|
val envelopes = messages.sortedBy { it.serverID!! }.map { message ->
|
||||||
try {
|
val senderPublicKey = message.sender!!
|
||||||
val senderPublicKey = message.sender!!
|
val builder = SignalServiceProtos.Envelope.newBuilder()
|
||||||
val builder = SignalServiceProtos.Envelope.newBuilder()
|
builder.type = SignalServiceProtos.Envelope.Type.SESSION_MESSAGE
|
||||||
builder.type = SignalServiceProtos.Envelope.Type.SESSION_MESSAGE
|
builder.source = senderPublicKey
|
||||||
builder.source = senderPublicKey
|
builder.sourceDevice = 1
|
||||||
builder.sourceDevice = 1
|
builder.content = message.toProto().toByteString()
|
||||||
builder.content = message.toProto().toByteString()
|
builder.timestamp = message.sentTimestamp
|
||||||
builder.timestamp = message.sentTimestamp
|
builder.build() to message.serverID
|
||||||
val envelope = builder.build()
|
}
|
||||||
val (parsedMessage, content) = MessageReceiver.parse(envelope.toByteArray(), message.serverID)
|
|
||||||
MessageReceiver.handle(parsedMessage, content, openGroupID)
|
envelopes.chunked(20).forEach { list ->
|
||||||
} catch (e: Exception) {
|
val parameters = list.map { (message, serverId) ->
|
||||||
Log.e("Loki", "Exception parsing message", e)
|
MessageReceiveParameters(message.toByteArray(), openGroupMessageServerID = serverId)
|
||||||
}
|
}
|
||||||
|
JobQueue.shared.add(BatchMessageReceiveJob(parameters, openGroupID))
|
||||||
}
|
}
|
||||||
|
|
||||||
val currentLastMessageServerID = storage.getLastMessageServerID(room, server) ?: 0
|
val currentLastMessageServerID = storage.getLastMessageServerID(room, server) ?: 0
|
||||||
@ -88,9 +84,6 @@ class OpenGroupPollerV2(private val server: String, private val executorService:
|
|||||||
if (actualMax > 0) {
|
if (actualMax > 0) {
|
||||||
storage.setLastMessageServerID(room, server, actualMax)
|
storage.setLastMessageServerID(room, server, actualMax)
|
||||||
}
|
}
|
||||||
if (messages.isNotEmpty()) {
|
|
||||||
JobQueue.shared.add(TrimThreadJob(threadId))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun handleDeletedMessages(room: String, openGroupID: String, deletions: List<OpenGroupAPIV2.MessageDeletion>) {
|
private fun handleDeletedMessages(room: String, openGroupID: String, deletions: List<OpenGroupAPIV2.MessageDeletion>) {
|
||||||
|
@ -3,12 +3,13 @@ package org.session.libsession.messaging.sending_receiving.pollers
|
|||||||
import nl.komponents.kovenant.*
|
import nl.komponents.kovenant.*
|
||||||
import nl.komponents.kovenant.functional.bind
|
import nl.komponents.kovenant.functional.bind
|
||||||
import org.session.libsession.messaging.MessagingModuleConfiguration
|
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||||
|
import org.session.libsession.messaging.jobs.BatchMessageReceiveJob
|
||||||
import org.session.libsession.messaging.jobs.JobQueue
|
import org.session.libsession.messaging.jobs.JobQueue
|
||||||
import org.session.libsession.messaging.jobs.MessageReceiveJob
|
import org.session.libsession.messaging.jobs.MessageReceiveParameters
|
||||||
import org.session.libsession.snode.SnodeAPI
|
import org.session.libsession.snode.SnodeAPI
|
||||||
import org.session.libsession.snode.SnodeModule
|
import org.session.libsession.snode.SnodeModule
|
||||||
import org.session.libsignal.utilities.Snode
|
|
||||||
import org.session.libsignal.utilities.Log
|
import org.session.libsignal.utilities.Log
|
||||||
|
import org.session.libsignal.utilities.Snode
|
||||||
import java.security.SecureRandom
|
import java.security.SecureRandom
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@ -91,10 +92,14 @@ class Poller {
|
|||||||
task { Unit } // The long polling connection has been canceled; don't recurse
|
task { Unit } // The long polling connection has been canceled; don't recurse
|
||||||
} else {
|
} else {
|
||||||
val messages = SnodeAPI.parseRawMessagesResponse(rawResponse, snode, userPublicKey)
|
val messages = SnodeAPI.parseRawMessagesResponse(rawResponse, snode, userPublicKey)
|
||||||
messages.forEach { (envelope, serverHash) ->
|
val parameters = messages.map { (envelope, serverHash) ->
|
||||||
val job = MessageReceiveJob(envelope.toByteArray(), serverHash)
|
MessageReceiveParameters(envelope.toByteArray(), serverHash = serverHash)
|
||||||
|
}
|
||||||
|
parameters.chunked(20).forEach { chunk ->
|
||||||
|
val job = BatchMessageReceiveJob(chunk)
|
||||||
JobQueue.shared.add(job)
|
JobQueue.shared.add(job)
|
||||||
}
|
}
|
||||||
|
|
||||||
poll(snode, deferred)
|
poll(snode, deferred)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -363,7 +363,7 @@ object TextSecurePreferences {
|
|||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getDirectCaptureCameraId(context: Context): Int {
|
fun getDirectCaptureCameraId(context: Context): Int {
|
||||||
return getIntegerPreference(context, DIRECT_CAPTURE_CAMERA_ID, Camera.CameraInfo.CAMERA_FACING_FRONT)
|
return getIntegerPreference(context, DIRECT_CAPTURE_CAMERA_ID, Camera.CameraInfo.CAMERA_FACING_BACK)
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
|
@ -29,7 +29,6 @@ import org.session.libsession.utilities.Address;
|
|||||||
import org.session.libsession.utilities.GroupRecord;
|
import org.session.libsession.utilities.GroupRecord;
|
||||||
import org.session.libsession.utilities.ListenableFutureTask;
|
import org.session.libsession.utilities.ListenableFutureTask;
|
||||||
import org.session.libsession.utilities.MaterialColor;
|
import org.session.libsession.utilities.MaterialColor;
|
||||||
import org.session.libsession.utilities.SoftHashMap;
|
|
||||||
import org.session.libsession.utilities.TextSecurePreferences;
|
import org.session.libsession.utilities.TextSecurePreferences;
|
||||||
import org.session.libsession.utilities.Util;
|
import org.session.libsession.utilities.Util;
|
||||||
import org.session.libsession.utilities.recipients.Recipient.RecipientSettings;
|
import org.session.libsession.utilities.recipients.Recipient.RecipientSettings;
|
||||||
@ -43,6 +42,7 @@ import java.util.LinkedList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
|
|
||||||
class RecipientProvider {
|
class RecipientProvider {
|
||||||
@ -222,17 +222,17 @@ class RecipientProvider {
|
|||||||
|
|
||||||
private static class RecipientCache {
|
private static class RecipientCache {
|
||||||
|
|
||||||
private final Map<Address,Recipient> cache = new SoftHashMap<>(1000);
|
private final Map<Address,Recipient> cache = new ConcurrentHashMap<>(1000);
|
||||||
|
|
||||||
public synchronized Recipient get(Address address) {
|
public Recipient get(Address address) {
|
||||||
return cache.get(address);
|
return cache.get(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void set(Address address, Recipient recipient) {
|
public void set(Address address, Recipient recipient) {
|
||||||
cache.put(address, recipient);
|
cache.put(address, recipient);
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized boolean remove(Address address) {
|
public boolean remove(Address address) {
|
||||||
return cache.remove(address) != null;
|
return cache.remove(address) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
|
|
||||||
all:
|
all:
|
||||||
protoc25 --java_out=../src/main/java/ SignalService.proto WebSocketResources.proto
|
protoc25 --java_out=../src/main/java/ SignalService.proto WebSocketResources.proto Utils.proto
|
||||||
|
10
libsignal/protobuf/Utils.proto
Normal file
10
libsignal/protobuf/Utils.proto
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
syntax = "proto2";
|
||||||
|
|
||||||
|
package signalservice;
|
||||||
|
|
||||||
|
option java_package = "org.session.libsignal.protos";
|
||||||
|
option java_outer_classname = "UtilProtos";
|
||||||
|
|
||||||
|
message ByteArrayList {
|
||||||
|
repeated bytes content = 1;
|
||||||
|
}
|
@ -0,0 +1,512 @@
|
|||||||
|
// Generated by the protocol buffer compiler. DO NOT EDIT!
|
||||||
|
// source: Utils.proto
|
||||||
|
|
||||||
|
package org.session.libsignal.protos;
|
||||||
|
|
||||||
|
public final class UtilProtos {
|
||||||
|
private UtilProtos() {}
|
||||||
|
public static void registerAllExtensions(
|
||||||
|
com.google.protobuf.ExtensionRegistry registry) {
|
||||||
|
}
|
||||||
|
public interface ByteArrayListOrBuilder
|
||||||
|
extends com.google.protobuf.MessageOrBuilder {
|
||||||
|
|
||||||
|
// repeated bytes content = 1;
|
||||||
|
/**
|
||||||
|
* <code>repeated bytes content = 1;</code>
|
||||||
|
*/
|
||||||
|
java.util.List<com.google.protobuf.ByteString> getContentList();
|
||||||
|
/**
|
||||||
|
* <code>repeated bytes content = 1;</code>
|
||||||
|
*/
|
||||||
|
int getContentCount();
|
||||||
|
/**
|
||||||
|
* <code>repeated bytes content = 1;</code>
|
||||||
|
*/
|
||||||
|
com.google.protobuf.ByteString getContent(int index);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Protobuf type {@code signalservice.ByteArrayList}
|
||||||
|
*/
|
||||||
|
public static final class ByteArrayList extends
|
||||||
|
com.google.protobuf.GeneratedMessage
|
||||||
|
implements ByteArrayListOrBuilder {
|
||||||
|
// Use ByteArrayList.newBuilder() to construct.
|
||||||
|
private ByteArrayList(com.google.protobuf.GeneratedMessage.Builder<?> builder) {
|
||||||
|
super(builder);
|
||||||
|
this.unknownFields = builder.getUnknownFields();
|
||||||
|
}
|
||||||
|
private ByteArrayList(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); }
|
||||||
|
|
||||||
|
private static final ByteArrayList defaultInstance;
|
||||||
|
public static ByteArrayList getDefaultInstance() {
|
||||||
|
return defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ByteArrayList getDefaultInstanceForType() {
|
||||||
|
return defaultInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final com.google.protobuf.UnknownFieldSet unknownFields;
|
||||||
|
@java.lang.Override
|
||||||
|
public final com.google.protobuf.UnknownFieldSet
|
||||||
|
getUnknownFields() {
|
||||||
|
return this.unknownFields;
|
||||||
|
}
|
||||||
|
private ByteArrayList(
|
||||||
|
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: {
|
||||||
|
if (!((mutable_bitField0_ & 0x00000001) == 0x00000001)) {
|
||||||
|
content_ = new java.util.ArrayList<com.google.protobuf.ByteString>();
|
||||||
|
mutable_bitField0_ |= 0x00000001;
|
||||||
|
}
|
||||||
|
content_.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_ & 0x00000001) == 0x00000001)) {
|
||||||
|
content_ = java.util.Collections.unmodifiableList(content_);
|
||||||
|
}
|
||||||
|
this.unknownFields = unknownFields.build();
|
||||||
|
makeExtensionsImmutable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public static final com.google.protobuf.Descriptors.Descriptor
|
||||||
|
getDescriptor() {
|
||||||
|
return org.session.libsignal.protos.UtilProtos.internal_static_signalservice_ByteArrayList_descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||||
|
internalGetFieldAccessorTable() {
|
||||||
|
return org.session.libsignal.protos.UtilProtos.internal_static_signalservice_ByteArrayList_fieldAccessorTable
|
||||||
|
.ensureFieldAccessorsInitialized(
|
||||||
|
org.session.libsignal.protos.UtilProtos.ByteArrayList.class, org.session.libsignal.protos.UtilProtos.ByteArrayList.Builder.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static com.google.protobuf.Parser<ByteArrayList> PARSER =
|
||||||
|
new com.google.protobuf.AbstractParser<ByteArrayList>() {
|
||||||
|
public ByteArrayList parsePartialFrom(
|
||||||
|
com.google.protobuf.CodedInputStream input,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return new ByteArrayList(input, extensionRegistry);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
@java.lang.Override
|
||||||
|
public com.google.protobuf.Parser<ByteArrayList> getParserForType() {
|
||||||
|
return PARSER;
|
||||||
|
}
|
||||||
|
|
||||||
|
// repeated bytes content = 1;
|
||||||
|
public static final int CONTENT_FIELD_NUMBER = 1;
|
||||||
|
private java.util.List<com.google.protobuf.ByteString> content_;
|
||||||
|
/**
|
||||||
|
* <code>repeated bytes content = 1;</code>
|
||||||
|
*/
|
||||||
|
public java.util.List<com.google.protobuf.ByteString>
|
||||||
|
getContentList() {
|
||||||
|
return content_;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>repeated bytes content = 1;</code>
|
||||||
|
*/
|
||||||
|
public int getContentCount() {
|
||||||
|
return content_.size();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>repeated bytes content = 1;</code>
|
||||||
|
*/
|
||||||
|
public com.google.protobuf.ByteString getContent(int index) {
|
||||||
|
return content_.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initFields() {
|
||||||
|
content_ = java.util.Collections.emptyList();
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
for (int i = 0; i < content_.size(); i++) {
|
||||||
|
output.writeBytes(1, content_.get(i));
|
||||||
|
}
|
||||||
|
getUnknownFields().writeTo(output);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int memoizedSerializedSize = -1;
|
||||||
|
public int getSerializedSize() {
|
||||||
|
int size = memoizedSerializedSize;
|
||||||
|
if (size != -1) return size;
|
||||||
|
|
||||||
|
size = 0;
|
||||||
|
{
|
||||||
|
int dataSize = 0;
|
||||||
|
for (int i = 0; i < content_.size(); i++) {
|
||||||
|
dataSize += com.google.protobuf.CodedOutputStream
|
||||||
|
.computeBytesSizeNoTag(content_.get(i));
|
||||||
|
}
|
||||||
|
size += dataSize;
|
||||||
|
size += 1 * getContentList().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.protos.UtilProtos.ByteArrayList parseFrom(
|
||||||
|
com.google.protobuf.ByteString data)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data);
|
||||||
|
}
|
||||||
|
public static org.session.libsignal.protos.UtilProtos.ByteArrayList 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.protos.UtilProtos.ByteArrayList parseFrom(byte[] data)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data);
|
||||||
|
}
|
||||||
|
public static org.session.libsignal.protos.UtilProtos.ByteArrayList parseFrom(
|
||||||
|
byte[] data,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws com.google.protobuf.InvalidProtocolBufferException {
|
||||||
|
return PARSER.parseFrom(data, extensionRegistry);
|
||||||
|
}
|
||||||
|
public static org.session.libsignal.protos.UtilProtos.ByteArrayList parseFrom(java.io.InputStream input)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return PARSER.parseFrom(input);
|
||||||
|
}
|
||||||
|
public static org.session.libsignal.protos.UtilProtos.ByteArrayList parseFrom(
|
||||||
|
java.io.InputStream input,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return PARSER.parseFrom(input, extensionRegistry);
|
||||||
|
}
|
||||||
|
public static org.session.libsignal.protos.UtilProtos.ByteArrayList parseDelimitedFrom(java.io.InputStream input)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return PARSER.parseDelimitedFrom(input);
|
||||||
|
}
|
||||||
|
public static org.session.libsignal.protos.UtilProtos.ByteArrayList parseDelimitedFrom(
|
||||||
|
java.io.InputStream input,
|
||||||
|
com.google.protobuf.ExtensionRegistryLite extensionRegistry)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return PARSER.parseDelimitedFrom(input, extensionRegistry);
|
||||||
|
}
|
||||||
|
public static org.session.libsignal.protos.UtilProtos.ByteArrayList parseFrom(
|
||||||
|
com.google.protobuf.CodedInputStream input)
|
||||||
|
throws java.io.IOException {
|
||||||
|
return PARSER.parseFrom(input);
|
||||||
|
}
|
||||||
|
public static org.session.libsignal.protos.UtilProtos.ByteArrayList 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.protos.UtilProtos.ByteArrayList 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.ByteArrayList}
|
||||||
|
*/
|
||||||
|
public static final class Builder extends
|
||||||
|
com.google.protobuf.GeneratedMessage.Builder<Builder>
|
||||||
|
implements org.session.libsignal.protos.UtilProtos.ByteArrayListOrBuilder {
|
||||||
|
public static final com.google.protobuf.Descriptors.Descriptor
|
||||||
|
getDescriptor() {
|
||||||
|
return org.session.libsignal.protos.UtilProtos.internal_static_signalservice_ByteArrayList_descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||||
|
internalGetFieldAccessorTable() {
|
||||||
|
return org.session.libsignal.protos.UtilProtos.internal_static_signalservice_ByteArrayList_fieldAccessorTable
|
||||||
|
.ensureFieldAccessorsInitialized(
|
||||||
|
org.session.libsignal.protos.UtilProtos.ByteArrayList.class, org.session.libsignal.protos.UtilProtos.ByteArrayList.Builder.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct using org.session.libsignal.protos.UtilProtos.ByteArrayList.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();
|
||||||
|
content_ = java.util.Collections.emptyList();
|
||||||
|
bitField0_ = (bitField0_ & ~0x00000001);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder clone() {
|
||||||
|
return create().mergeFrom(buildPartial());
|
||||||
|
}
|
||||||
|
|
||||||
|
public com.google.protobuf.Descriptors.Descriptor
|
||||||
|
getDescriptorForType() {
|
||||||
|
return org.session.libsignal.protos.UtilProtos.internal_static_signalservice_ByteArrayList_descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public org.session.libsignal.protos.UtilProtos.ByteArrayList getDefaultInstanceForType() {
|
||||||
|
return org.session.libsignal.protos.UtilProtos.ByteArrayList.getDefaultInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
public org.session.libsignal.protos.UtilProtos.ByteArrayList build() {
|
||||||
|
org.session.libsignal.protos.UtilProtos.ByteArrayList result = buildPartial();
|
||||||
|
if (!result.isInitialized()) {
|
||||||
|
throw newUninitializedMessageException(result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public org.session.libsignal.protos.UtilProtos.ByteArrayList buildPartial() {
|
||||||
|
org.session.libsignal.protos.UtilProtos.ByteArrayList result = new org.session.libsignal.protos.UtilProtos.ByteArrayList(this);
|
||||||
|
int from_bitField0_ = bitField0_;
|
||||||
|
if (((bitField0_ & 0x00000001) == 0x00000001)) {
|
||||||
|
content_ = java.util.Collections.unmodifiableList(content_);
|
||||||
|
bitField0_ = (bitField0_ & ~0x00000001);
|
||||||
|
}
|
||||||
|
result.content_ = content_;
|
||||||
|
onBuilt();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder mergeFrom(com.google.protobuf.Message other) {
|
||||||
|
if (other instanceof org.session.libsignal.protos.UtilProtos.ByteArrayList) {
|
||||||
|
return mergeFrom((org.session.libsignal.protos.UtilProtos.ByteArrayList)other);
|
||||||
|
} else {
|
||||||
|
super.mergeFrom(other);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder mergeFrom(org.session.libsignal.protos.UtilProtos.ByteArrayList other) {
|
||||||
|
if (other == org.session.libsignal.protos.UtilProtos.ByteArrayList.getDefaultInstance()) return this;
|
||||||
|
if (!other.content_.isEmpty()) {
|
||||||
|
if (content_.isEmpty()) {
|
||||||
|
content_ = other.content_;
|
||||||
|
bitField0_ = (bitField0_ & ~0x00000001);
|
||||||
|
} else {
|
||||||
|
ensureContentIsMutable();
|
||||||
|
content_.addAll(other.content_);
|
||||||
|
}
|
||||||
|
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.protos.UtilProtos.ByteArrayList parsedMessage = null;
|
||||||
|
try {
|
||||||
|
parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
|
||||||
|
} catch (com.google.protobuf.InvalidProtocolBufferException e) {
|
||||||
|
parsedMessage = (org.session.libsignal.protos.UtilProtos.ByteArrayList) e.getUnfinishedMessage();
|
||||||
|
throw e;
|
||||||
|
} finally {
|
||||||
|
if (parsedMessage != null) {
|
||||||
|
mergeFrom(parsedMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
private int bitField0_;
|
||||||
|
|
||||||
|
// repeated bytes content = 1;
|
||||||
|
private java.util.List<com.google.protobuf.ByteString> content_ = java.util.Collections.emptyList();
|
||||||
|
private void ensureContentIsMutable() {
|
||||||
|
if (!((bitField0_ & 0x00000001) == 0x00000001)) {
|
||||||
|
content_ = new java.util.ArrayList<com.google.protobuf.ByteString>(content_);
|
||||||
|
bitField0_ |= 0x00000001;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>repeated bytes content = 1;</code>
|
||||||
|
*/
|
||||||
|
public java.util.List<com.google.protobuf.ByteString>
|
||||||
|
getContentList() {
|
||||||
|
return java.util.Collections.unmodifiableList(content_);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>repeated bytes content = 1;</code>
|
||||||
|
*/
|
||||||
|
public int getContentCount() {
|
||||||
|
return content_.size();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>repeated bytes content = 1;</code>
|
||||||
|
*/
|
||||||
|
public com.google.protobuf.ByteString getContent(int index) {
|
||||||
|
return content_.get(index);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>repeated bytes content = 1;</code>
|
||||||
|
*/
|
||||||
|
public Builder setContent(
|
||||||
|
int index, com.google.protobuf.ByteString value) {
|
||||||
|
if (value == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
ensureContentIsMutable();
|
||||||
|
content_.set(index, value);
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>repeated bytes content = 1;</code>
|
||||||
|
*/
|
||||||
|
public Builder addContent(com.google.protobuf.ByteString value) {
|
||||||
|
if (value == null) {
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
|
ensureContentIsMutable();
|
||||||
|
content_.add(value);
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>repeated bytes content = 1;</code>
|
||||||
|
*/
|
||||||
|
public Builder addAllContent(
|
||||||
|
java.lang.Iterable<? extends com.google.protobuf.ByteString> values) {
|
||||||
|
ensureContentIsMutable();
|
||||||
|
super.addAll(values, content_);
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* <code>repeated bytes content = 1;</code>
|
||||||
|
*/
|
||||||
|
public Builder clearContent() {
|
||||||
|
content_ = java.util.Collections.emptyList();
|
||||||
|
bitField0_ = (bitField0_ & ~0x00000001);
|
||||||
|
onChanged();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// @@protoc_insertion_point(builder_scope:signalservice.ByteArrayList)
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
defaultInstance = new ByteArrayList(true);
|
||||||
|
defaultInstance.initFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
// @@protoc_insertion_point(class_scope:signalservice.ByteArrayList)
|
||||||
|
}
|
||||||
|
|
||||||
|
private static com.google.protobuf.Descriptors.Descriptor
|
||||||
|
internal_static_signalservice_ByteArrayList_descriptor;
|
||||||
|
private static
|
||||||
|
com.google.protobuf.GeneratedMessage.FieldAccessorTable
|
||||||
|
internal_static_signalservice_ByteArrayList_fieldAccessorTable;
|
||||||
|
|
||||||
|
public static com.google.protobuf.Descriptors.FileDescriptor
|
||||||
|
getDescriptor() {
|
||||||
|
return descriptor;
|
||||||
|
}
|
||||||
|
private static com.google.protobuf.Descriptors.FileDescriptor
|
||||||
|
descriptor;
|
||||||
|
static {
|
||||||
|
java.lang.String[] descriptorData = {
|
||||||
|
"\n\013Utils.proto\022\rsignalservice\" \n\rByteArra" +
|
||||||
|
"yList\022\017\n\007content\030\001 \003(\014B*\n\034org.session.li" +
|
||||||
|
"bsignal.protosB\nUtilProtos"
|
||||||
|
};
|
||||||
|
com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
|
||||||
|
new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
|
||||||
|
public com.google.protobuf.ExtensionRegistry assignDescriptors(
|
||||||
|
com.google.protobuf.Descriptors.FileDescriptor root) {
|
||||||
|
descriptor = root;
|
||||||
|
internal_static_signalservice_ByteArrayList_descriptor =
|
||||||
|
getDescriptor().getMessageTypes().get(0);
|
||||||
|
internal_static_signalservice_ByteArrayList_fieldAccessorTable = new
|
||||||
|
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||||
|
internal_static_signalservice_ByteArrayList_descriptor,
|
||||||
|
new java.lang.String[] { "Content", });
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
com.google.protobuf.Descriptors.FileDescriptor
|
||||||
|
.internalBuildGeneratedFileFrom(descriptorData,
|
||||||
|
new com.google.protobuf.Descriptors.FileDescriptor[] {
|
||||||
|
}, assigner);
|
||||||
|
}
|
||||||
|
|
||||||
|
// @@protoc_insertion_point(outer_class_scope)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user