mirror of
https://github.com/oxen-io/session-android.git
synced 2025-10-19 09:31:47 +00:00
Merge remote-tracking branch 'upstream/dev' into libsession-integration
# Conflicts: # app/src/main/java/org/thoughtcrime/securesms/conversation/v2/ConversationActivityV2.kt # app/src/main/java/org/thoughtcrime/securesms/database/ThreadDatabase.java # libsession/src/main/java/org/session/libsession/messaging/sending_receiving/MessageSender.kt # libsession/src/main/java/org/session/libsession/snode/SnodeAPI.kt
This commit is contained in:
@@ -98,19 +98,19 @@ class BatchMessageReceiveJob(
|
||||
} catch (e: Exception) {
|
||||
when (e) {
|
||||
is MessageReceiver.Error.DuplicateMessage, MessageReceiver.Error.SelfSend -> {
|
||||
Log.i(TAG, "Couldn't receive message, failed with error: ${e.message}")
|
||||
Log.i(TAG, "Couldn't receive message, failed with error: ${e.message} (id: $id)")
|
||||
}
|
||||
is MessageReceiver.Error -> {
|
||||
if (!e.isRetryable) {
|
||||
Log.e(TAG, "Couldn't receive message, failed permanently", e)
|
||||
Log.e(TAG, "Couldn't receive message, failed permanently (id: $id)", e)
|
||||
}
|
||||
else {
|
||||
Log.e(TAG, "Couldn't receive message, failed", e)
|
||||
Log.e(TAG, "Couldn't receive message, failed (id: $id)", e)
|
||||
failures += messageParameters
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
Log.e(TAG, "Couldn't receive message, failed", e)
|
||||
Log.e(TAG, "Couldn't receive message, failed (id: $id)", e)
|
||||
failures += messageParameters
|
||||
}
|
||||
}
|
||||
@@ -166,11 +166,11 @@ class BatchMessageReceiveJob(
|
||||
else -> MessageReceiver.handle(message, proto, openGroupID)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Couldn't process message.", e)
|
||||
Log.e(TAG, "Couldn't process message (id: $id)", e)
|
||||
if (e is MessageReceiver.Error && !e.isRetryable) {
|
||||
Log.e(TAG, "Message failed permanently",e)
|
||||
Log.e(TAG, "Message failed permanently (id: $id)", e)
|
||||
} else {
|
||||
Log.e(TAG, "Message failed",e)
|
||||
Log.e(TAG, "Message failed (id: $id)", e)
|
||||
failures += parameters
|
||||
}
|
||||
}
|
||||
@@ -199,12 +199,12 @@ class BatchMessageReceiveJob(
|
||||
}
|
||||
|
||||
private fun handleSuccess(dispatcherName: String) {
|
||||
Log.i(TAG, "Completed processing of ${messages.size} messages")
|
||||
Log.i(TAG, "Completed processing of ${messages.size} messages (id: $id)")
|
||||
this.delegate?.handleJobSucceeded(this, dispatcherName)
|
||||
}
|
||||
|
||||
private fun handleFailure(dispatcherName: String) {
|
||||
Log.i(TAG, "Handling failure of ${failures.size} messages (${messages.size - failures.size} processed successfully)")
|
||||
Log.i(TAG, "Handling failure of ${failures.size} messages (${messages.size - failures.size} processed successfully) (id: $id)")
|
||||
this.delegate?.handleJobFailed(this, dispatcherName, Exception("One or more jobs resulted in failure"))
|
||||
}
|
||||
|
||||
|
@@ -3,6 +3,7 @@ package org.session.libsession.messaging.jobs
|
||||
import org.session.libsession.messaging.MessagingModuleConfiguration
|
||||
import org.session.libsession.messaging.open_groups.OpenGroupApi
|
||||
import org.session.libsession.messaging.utilities.Data
|
||||
import org.session.libsession.snode.SnodeAPI
|
||||
import org.session.libsession.utilities.GroupUtil
|
||||
|
||||
class GroupAvatarDownloadJob(val server: String, val room: String, val imageId: String?) : Job {
|
||||
@@ -43,7 +44,7 @@ class GroupAvatarDownloadJob(val server: String, val room: String, val imageId:
|
||||
|
||||
val groupId = GroupUtil.getEncodedOpenGroupID("$server.$room".toByteArray())
|
||||
storage.updateProfilePicture(groupId, bytes)
|
||||
storage.updateTimestampUpdated(groupId, System.currentTimeMillis())
|
||||
storage.updateTimestampUpdated(groupId, SnodeAPI.nowWithOffset)
|
||||
delegate?.handleJobSucceeded(this, dispatcherName)
|
||||
} catch (e: Exception) {
|
||||
delegate?.handleJobFailed(this, dispatcherName, e)
|
||||
|
@@ -23,6 +23,7 @@ import org.session.libsession.messaging.utilities.SessionId
|
||||
import org.session.libsession.messaging.utilities.SodiumUtilities
|
||||
import org.session.libsession.snode.OnionRequestAPI
|
||||
import org.session.libsession.snode.OnionResponse
|
||||
import org.session.libsession.snode.SnodeAPI
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.session.libsignal.utilities.Base64.decode
|
||||
import org.session.libsignal.utilities.Base64.encodeBytes
|
||||
@@ -303,7 +304,7 @@ object OpenGroupApi {
|
||||
val headers = request.headers.toMutableMap()
|
||||
if (request.isAuthRequired) {
|
||||
val nonce = sodium.nonce(16)
|
||||
val timestamp = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())
|
||||
val timestamp = TimeUnit.MILLISECONDS.toSeconds(SnodeAPI.nowWithOffset)
|
||||
var pubKey = ""
|
||||
var signature = ByteArray(Sign.BYTES)
|
||||
var bodyHash = ByteArray(0)
|
||||
|
@@ -15,6 +15,7 @@ import org.session.libsession.messaging.messages.control.UnsendRequest
|
||||
import org.session.libsession.messaging.messages.visible.VisibleMessage
|
||||
import org.session.libsession.messaging.utilities.SessionId
|
||||
import org.session.libsession.messaging.utilities.SodiumUtilities
|
||||
import org.session.libsession.snode.SnodeAPI
|
||||
import org.session.libsignal.crypto.PushTransportDetails
|
||||
import org.session.libsignal.protos.SignalServiceProtos
|
||||
import org.session.libsignal.utilities.IdPrefix
|
||||
@@ -156,7 +157,7 @@ object MessageReceiver {
|
||||
message.sender = sender
|
||||
message.recipient = userPublicKey
|
||||
message.sentTimestamp = envelope.timestamp
|
||||
message.receivedTimestamp = if (envelope.hasServerTimestamp()) envelope.serverTimestamp else System.currentTimeMillis()
|
||||
message.receivedTimestamp = if (envelope.hasServerTimestamp()) envelope.serverTimestamp else SnodeAPI.nowWithOffset
|
||||
message.groupPublicKey = groupPublicKey
|
||||
message.openGroupServerMessageID = openGroupServerID
|
||||
// Validate
|
||||
|
@@ -199,7 +199,20 @@ object MessageSender {
|
||||
val hash = it["hash"] as? String
|
||||
message.serverHash = hash
|
||||
handleSuccessfulMessageSend(message, destination, isSyncMessage)
|
||||
val shouldNotify = ((message is VisibleMessage || message is UnsendRequest || message is CallMessage) && !isSyncMessage)
|
||||
|
||||
val shouldNotify: Boolean = when (message) {
|
||||
is VisibleMessage, is UnsendRequest -> !isSyncMessage
|
||||
is CallMessage -> {
|
||||
// Note: Other 'CallMessage' types are too big to send as push notifications
|
||||
// so only send the 'preOffer' message as a notification
|
||||
when (message.type) {
|
||||
SignalServiceProtos.CallMessage.Type.PRE_OFFER -> true
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
|
||||
/*
|
||||
if (message is ClosedGroupControlMessage && message.kind is ClosedGroupControlMessage.Kind.New) {
|
||||
shouldNotify = true
|
||||
@@ -229,7 +242,7 @@ object MessageSender {
|
||||
val deferred = deferred<Unit, Exception>()
|
||||
val storage = MessagingModuleConfiguration.shared.storage
|
||||
if (message.sentTimestamp == null) {
|
||||
message.sentTimestamp = System.currentTimeMillis()
|
||||
message.sentTimestamp = SnodeAPI.nowWithOffset
|
||||
}
|
||||
val userEdKeyPair = MessagingModuleConfiguration.shared.getUserED25519KeyPair()!!
|
||||
var serverCapabilities = listOf<String>()
|
||||
|
@@ -50,11 +50,11 @@ fun MessageSender.create(name: String, members: Collection<String>): Promise<Str
|
||||
val admins = setOf( userPublicKey )
|
||||
val adminsAsData = admins.map { ByteString.copyFrom(Hex.fromStringCondensed(it)) }
|
||||
storage.createGroup(groupID, name, LinkedList(members.map { Address.fromSerialized(it) }),
|
||||
null, null, LinkedList(admins.map { Address.fromSerialized(it) }), System.currentTimeMillis())
|
||||
null, null, LinkedList(admins.map { Address.fromSerialized(it) }), SnodeAPI.nowWithOffset)
|
||||
storage.setProfileSharing(Address.fromSerialized(groupID), true)
|
||||
// Send a closed group update message to all members individually
|
||||
val closedGroupUpdateKind = ClosedGroupControlMessage.Kind.New(ByteString.copyFrom(Hex.fromStringCondensed(groupPublicKey)), name, encryptionKeyPair, membersAsData, adminsAsData, 0)
|
||||
val sentTime = System.currentTimeMillis()
|
||||
val sentTime = SnodeAPI.nowWithOffset
|
||||
for (member in members) {
|
||||
val closedGroupControlMessage = ClosedGroupControlMessage(closedGroupUpdateKind)
|
||||
closedGroupControlMessage.sentTimestamp = sentTime
|
||||
@@ -97,7 +97,7 @@ fun MessageSender.setName(groupPublicKey: String, newName: String) {
|
||||
val admins = group.admins.map { it.serialize() }
|
||||
// Send the update to the group
|
||||
val kind = ClosedGroupControlMessage.Kind.NameChange(newName)
|
||||
val sentTime = System.currentTimeMillis()
|
||||
val sentTime = SnodeAPI.nowWithOffset
|
||||
val closedGroupControlMessage = ClosedGroupControlMessage(kind)
|
||||
closedGroupControlMessage.sentTimestamp = sentTime
|
||||
send(closedGroupControlMessage, Address.fromSerialized(groupID))
|
||||
@@ -137,7 +137,7 @@ fun MessageSender.addMembers(groupPublicKey: String, membersToAdd: List<String>)
|
||||
val name = group.title
|
||||
// Send the update to the group
|
||||
val memberUpdateKind = ClosedGroupControlMessage.Kind.MembersAdded(newMembersAsData)
|
||||
val sentTime = System.currentTimeMillis()
|
||||
val sentTime = SnodeAPI.nowWithOffset
|
||||
val closedGroupControlMessage = ClosedGroupControlMessage(memberUpdateKind)
|
||||
closedGroupControlMessage.sentTimestamp = sentTime
|
||||
send(closedGroupControlMessage, Address.fromSerialized(groupID))
|
||||
@@ -151,7 +151,7 @@ fun MessageSender.addMembers(groupPublicKey: String, membersToAdd: List<String>)
|
||||
// updates from before that timestamp. By setting the timestamp of the message below to a value
|
||||
// greater than that of the `MembersAdded` message, we ensure that newly added members ignore
|
||||
// the `MembersAdded` message.
|
||||
closedGroupControlMessage.sentTimestamp = System.currentTimeMillis()
|
||||
closedGroupControlMessage.sentTimestamp = SnodeAPI.nowWithOffset
|
||||
send(closedGroupControlMessage, Address.fromSerialized(member))
|
||||
}
|
||||
// Notify the user
|
||||
@@ -192,7 +192,7 @@ fun MessageSender.removeMembers(groupPublicKey: String, membersToRemove: List<St
|
||||
val name = group.title
|
||||
// Send the update to the group
|
||||
val memberUpdateKind = ClosedGroupControlMessage.Kind.MembersRemoved(removeMembersAsData)
|
||||
val sentTime = System.currentTimeMillis()
|
||||
val sentTime = SnodeAPI.nowWithOffset
|
||||
val closedGroupControlMessage = ClosedGroupControlMessage(memberUpdateKind)
|
||||
closedGroupControlMessage.sentTimestamp = sentTime
|
||||
send(closedGroupControlMessage, Address.fromSerialized(groupID))
|
||||
@@ -223,7 +223,7 @@ fun MessageSender.leave(groupPublicKey: String, notifyUser: Boolean = true): Pro
|
||||
val name = group.title
|
||||
// Send the update to the group
|
||||
val closedGroupControlMessage = ClosedGroupControlMessage(ClosedGroupControlMessage.Kind.MemberLeft())
|
||||
val sentTime = System.currentTimeMillis()
|
||||
val sentTime = SnodeAPI.nowWithOffset
|
||||
closedGroupControlMessage.sentTimestamp = sentTime
|
||||
storage.setActive(groupID, false)
|
||||
sendNonDurably(closedGroupControlMessage, Address.fromSerialized(groupID)).success {
|
||||
|
@@ -54,10 +54,9 @@ class ClosedGroupPollerV2 {
|
||||
setUpPolling(groupPublicKey)
|
||||
}
|
||||
|
||||
fun stop() {
|
||||
val storage = MessagingModuleConfiguration.shared.storage
|
||||
val allGroupPublicKeys = storage.getAllClosedGroupPublicKeys()
|
||||
allGroupPublicKeys.iterator().forEach { stopPolling(it) }
|
||||
fun stopAll() {
|
||||
futures.forEach { it.value.cancel(false) }
|
||||
isPolling.forEach { isPolling[it.key] = false }
|
||||
}
|
||||
|
||||
fun stopPolling(groupPublicKey: String) {
|
||||
|
@@ -26,6 +26,7 @@ import org.session.libsignal.utilities.ThreadUtils
|
||||
import org.session.libsignal.utilities.recover
|
||||
import org.session.libsignal.utilities.toHexString
|
||||
import java.util.Date
|
||||
import java.util.concurrent.atomic.AtomicReference
|
||||
import kotlin.collections.set
|
||||
|
||||
private typealias Path = List<Snode>
|
||||
@@ -43,13 +44,27 @@ object OnionRequestAPI {
|
||||
private val snodeFailureCount = mutableMapOf<Snode, Int>()
|
||||
|
||||
var guardSnodes = setOf<Snode>()
|
||||
var _paths: AtomicReference<List<Path>?> = AtomicReference(null)
|
||||
var paths: List<Path> // Not a set to ensure we consistently show the same path to the user
|
||||
get() = database.getOnionRequestPaths()
|
||||
get() {
|
||||
val paths = _paths.get()
|
||||
|
||||
if (paths != null) { return paths }
|
||||
|
||||
// Storing this in an atomic variable as it was causing a number of background
|
||||
// ANRs when this value was accessed via the main thread after tapping on
|
||||
// a notification)
|
||||
val result = database.getOnionRequestPaths()
|
||||
_paths.set(result)
|
||||
return result
|
||||
}
|
||||
set(newValue) {
|
||||
if (newValue.isEmpty()) {
|
||||
database.clearOnionRequestPaths()
|
||||
_paths.set(null)
|
||||
} else {
|
||||
database.setOnionRequestPaths(newValue)
|
||||
_paths.set(newValue)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -57,7 +57,7 @@ object SnodeAPI {
|
||||
internal var clockOffset = 0L
|
||||
|
||||
@JvmStatic
|
||||
val nowWithOffset
|
||||
public val nowWithOffset
|
||||
get() = System.currentTimeMillis() + clockOffset
|
||||
|
||||
internal var forkInfo by observable(database.getForkInfo()) { _, oldValue, newValue ->
|
||||
@@ -590,7 +590,7 @@ object SnodeAPI {
|
||||
val parameters = message.toJSON().toMutableMap<String,Any>()
|
||||
// Construct signature
|
||||
if (requiresAuth) {
|
||||
val sigTimestamp = System.currentTimeMillis() + SnodeAPI.clockOffset
|
||||
val sigTimestamp = nowWithOffset
|
||||
val ed25519PublicKey = userED25519KeyPair.publicKey.asHexString
|
||||
val signature = ByteArray(Sign.BYTES)
|
||||
// assume namespace here is non-zero, as zero namespace doesn't require auth
|
||||
|
@@ -26,7 +26,7 @@ class SSKEnvironment(
|
||||
|
||||
interface ProfileManagerProtocol {
|
||||
companion object {
|
||||
const val NAME_PADDED_LENGTH = 26
|
||||
const val NAME_PADDED_LENGTH = 64
|
||||
}
|
||||
|
||||
fun setNickname(context: Context, recipient: Recipient, nickname: String?)
|
||||
@@ -55,4 +55,4 @@ class SSKEnvironment(
|
||||
shared = SSKEnvironment(typingIndicators, readReceiptManager, profileManager, notificationManager, messageExpirationManager)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user