mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-30 13:35:18 +00:00
Merge branch 'refactor' of https://github.com/RyanRory/loki-messenger-android into refactor
This commit is contained in:
commit
d7b0c84f22
@ -1,52 +1,68 @@
|
|||||||
//package org.thoughtcrime.securesms.attachments
|
package org.thoughtcrime.securesms.attachments
|
||||||
//
|
|
||||||
//import android.content.Context
|
import android.content.Context
|
||||||
//import com.google.protobuf.ByteString
|
import com.google.protobuf.ByteString
|
||||||
//import org.session.libsession.database.dto.DatabaseAttachmentDTO
|
import org.session.libsession.database.dto.DatabaseAttachmentDTO
|
||||||
//import org.session.libsession.database.MessageDataProvider
|
import org.session.libsession.database.MessageDataProvider
|
||||||
//import org.session.libsignal.service.internal.push.SignalServiceProtos
|
import org.session.libsession.database.dto.AttachmentState
|
||||||
//import org.thoughtcrime.securesms.database.Database
|
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||||
//import org.thoughtcrime.securesms.database.DatabaseFactory
|
import org.thoughtcrime.securesms.database.Database
|
||||||
//import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
|
import org.thoughtcrime.securesms.database.DatabaseFactory
|
||||||
//import org.thoughtcrime.securesms.util.MediaUtil
|
import org.thoughtcrime.securesms.database.SmsDatabase
|
||||||
//
|
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper
|
||||||
//class DatabaseAttachmentProvider(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), MessageDataProvider {
|
import org.thoughtcrime.securesms.jobs.AttachmentUploadJob
|
||||||
// override fun getAttachment(uniqueID: String): DatabaseAttachmentDTO? {
|
import org.thoughtcrime.securesms.util.MediaUtil
|
||||||
//
|
|
||||||
// val attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context)
|
class DatabaseAttachmentProvider(context: Context, helper: SQLCipherOpenHelper) : Database(context, helper), MessageDataProvider {
|
||||||
// val uniqueID = uniqueID.toLongOrNull() ?: return null
|
override fun getAttachment(attachmentId: Long): DatabaseAttachmentDTO? {
|
||||||
// val attachmentID = AttachmentId(0, uniqueID)
|
val attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context)
|
||||||
// val databaseAttachment = attachmentDatabase.getAttachment(attachmentID) ?: return null
|
val databaseAttachment = attachmentDatabase.getAttachment(AttachmentId(attachmentId, 0)) ?: return null
|
||||||
//
|
return databaseAttachment.toDTO()
|
||||||
// return databaseAttachment.toDTO()
|
}
|
||||||
// }
|
|
||||||
//
|
override fun setAttachmentState(attachmentState: AttachmentState, attachment: DatabaseAttachmentDTO, messageID: Long) {
|
||||||
//}
|
val attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context)
|
||||||
//
|
attachmentDatabase.setTransferState(messageID, AttachmentId(attachment.attachmentId, 0), attachmentState.value)
|
||||||
//// Extension to DatabaseAttachment class
|
}
|
||||||
//
|
|
||||||
//fun DatabaseAttachment.toDTO(): DatabaseAttachmentDTO {
|
@Throws(Exception::class)
|
||||||
// var databaseAttachmentDTO = DatabaseAttachmentDTO()
|
override fun uploadAttachment(attachmentId: Long) {
|
||||||
// databaseAttachmentDTO.contentType = this.contentType
|
val attachmentUploadJob = AttachmentUploadJob(AttachmentId(attachmentId, 0), null)
|
||||||
// databaseAttachmentDTO.fileName = this.fileName
|
attachmentUploadJob.onRun()
|
||||||
// databaseAttachmentDTO.caption = this.caption
|
}
|
||||||
//
|
|
||||||
// databaseAttachmentDTO.size = this.size.toInt()
|
override fun isOutgoingMessage(timestamp: Long): Boolean {
|
||||||
// databaseAttachmentDTO.key = ByteString.copyFrom(this.key?.toByteArray())
|
val smsDatabase = DatabaseFactory.getSmsDatabase(context)
|
||||||
// databaseAttachmentDTO.digest = ByteString.copyFrom(this.digest)
|
return smsDatabase.isOutgoingMessage(timestamp)
|
||||||
// databaseAttachmentDTO.flags = if (this.isVoiceNote) SignalServiceProtos.AttachmentPointer.Flags.VOICE_MESSAGE.number else 0
|
}
|
||||||
//
|
|
||||||
// databaseAttachmentDTO.url = this.url
|
}
|
||||||
//
|
|
||||||
// if (this.shouldHaveImageSize()) {
|
// Extension to DatabaseAttachment class
|
||||||
// databaseAttachmentDTO.shouldHaveImageSize = true
|
|
||||||
// databaseAttachmentDTO.width = this.width
|
fun DatabaseAttachment.toDTO(): DatabaseAttachmentDTO {
|
||||||
// databaseAttachmentDTO.height = this.height
|
var databaseAttachmentDTO = DatabaseAttachmentDTO()
|
||||||
// }
|
databaseAttachmentDTO.attachmentId = this.attachmentId.rowId
|
||||||
//
|
databaseAttachmentDTO.contentType = this.contentType
|
||||||
// return databaseAttachmentDTO
|
databaseAttachmentDTO.fileName = this.fileName
|
||||||
//}
|
databaseAttachmentDTO.caption = this.caption
|
||||||
//
|
|
||||||
//fun DatabaseAttachment.shouldHaveImageSize(): Boolean {
|
databaseAttachmentDTO.size = this.size.toInt()
|
||||||
// return (MediaUtil.isVideo(this) || MediaUtil.isImage(this) || MediaUtil.isGif(this));
|
databaseAttachmentDTO.key = ByteString.copyFrom(this.key?.toByteArray())
|
||||||
//}
|
databaseAttachmentDTO.digest = ByteString.copyFrom(this.digest)
|
||||||
|
databaseAttachmentDTO.flags = if (this.isVoiceNote) SignalServiceProtos.AttachmentPointer.Flags.VOICE_MESSAGE.number else 0
|
||||||
|
|
||||||
|
databaseAttachmentDTO.url = this.url
|
||||||
|
|
||||||
|
if (this.shouldHaveImageSize()) {
|
||||||
|
databaseAttachmentDTO.shouldHaveImageSize = true
|
||||||
|
databaseAttachmentDTO.width = this.width
|
||||||
|
databaseAttachmentDTO.height = this.height
|
||||||
|
}
|
||||||
|
|
||||||
|
return databaseAttachmentDTO
|
||||||
|
}
|
||||||
|
|
||||||
|
fun DatabaseAttachment.shouldHaveImageSize(): Boolean {
|
||||||
|
return (MediaUtil.isVideo(this) || MediaUtil.isImage(this) || MediaUtil.isGif(this));
|
||||||
|
}
|
@ -1,9 +1,18 @@
|
|||||||
package org.session.libsession.database
|
package org.session.libsession.database
|
||||||
|
|
||||||
|
import org.session.libsession.database.dto.AttachmentState
|
||||||
import org.session.libsession.database.dto.DatabaseAttachmentDTO
|
import org.session.libsession.database.dto.DatabaseAttachmentDTO
|
||||||
|
import org.session.libsession.messaging.messages.visible.Attachment
|
||||||
|
|
||||||
interface MessageDataProvider {
|
interface MessageDataProvider {
|
||||||
|
|
||||||
fun getAttachment(uniqueID: String): DatabaseAttachmentDTO?
|
fun getAttachment(attachmentId: Long): DatabaseAttachmentDTO?
|
||||||
|
|
||||||
|
fun setAttachmentState(attachmentState: AttachmentState, attachment: DatabaseAttachmentDTO, messageID: Long)
|
||||||
|
|
||||||
|
fun isOutgoingMessage(timestamp: Long): Boolean
|
||||||
|
|
||||||
|
@Throws(Exception::class)
|
||||||
|
fun uploadAttachment(attachmentId: Long)
|
||||||
|
|
||||||
}
|
}
|
@ -6,6 +6,8 @@ import org.session.libsignal.service.internal.push.SignalServiceProtos
|
|||||||
import kotlin.math.round
|
import kotlin.math.round
|
||||||
|
|
||||||
class DatabaseAttachmentDTO {
|
class DatabaseAttachmentDTO {
|
||||||
|
var attachmentId: Long = 0
|
||||||
|
|
||||||
var contentType: String? = null
|
var contentType: String? = null
|
||||||
|
|
||||||
var fileName: String? = null
|
var fileName: String? = null
|
||||||
|
@ -35,7 +35,7 @@ interface StorageProtocol {
|
|||||||
fun markJobAsSucceeded(job: Job)
|
fun markJobAsSucceeded(job: Job)
|
||||||
fun markJobAsFailed(job: Job)
|
fun markJobAsFailed(job: Job)
|
||||||
fun getAllPendingJobs(type: String): List<Job>
|
fun getAllPendingJobs(type: String): List<Job>
|
||||||
fun getAttachmentUploadJob(attachmentID: String): AttachmentUploadJob?
|
fun getAttachmentUploadJob(attachmentID: Long): AttachmentUploadJob?
|
||||||
fun getMessageSendJob(messageSendJobID: String): MessageSendJob?
|
fun getMessageSendJob(messageSendJobID: String): MessageSendJob?
|
||||||
fun resumeMessageSendJobIfNeeded(messageSendJobID: String)
|
fun resumeMessageSendJobIfNeeded(messageSendJobID: String)
|
||||||
fun isJobCanceled(job: Job): Boolean
|
fun isJobCanceled(job: Job): Boolean
|
||||||
|
@ -4,12 +4,12 @@ import nl.komponents.kovenant.Promise
|
|||||||
import nl.komponents.kovenant.functional.bind
|
import nl.komponents.kovenant.functional.bind
|
||||||
import nl.komponents.kovenant.functional.map
|
import nl.komponents.kovenant.functional.map
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
|
import org.session.libsession.messaging.utilities.DotNetAPI
|
||||||
import org.session.libsignal.libsignal.logging.Log
|
import org.session.libsignal.libsignal.logging.Log
|
||||||
import org.session.libsignal.libsignal.util.Hex
|
import org.session.libsignal.libsignal.util.Hex
|
||||||
import org.session.libsignal.service.internal.util.Base64
|
import org.session.libsignal.service.internal.util.Base64
|
||||||
import org.session.libsignal.service.internal.util.JsonUtil
|
import org.session.libsignal.service.internal.util.JsonUtil
|
||||||
import org.session.libsignal.service.loki.api.SnodeAPI
|
import org.session.libsignal.service.loki.api.SnodeAPI
|
||||||
import org.session.libsignal.service.loki.api.LokiDotNetAPI
|
|
||||||
import org.session.libsignal.service.loki.api.onionrequests.OnionRequestAPI
|
import org.session.libsignal.service.loki.api.onionrequests.OnionRequestAPI
|
||||||
import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol
|
import org.session.libsignal.service.loki.database.LokiAPIDatabaseProtocol
|
||||||
import org.session.libsignal.service.loki.protocol.shelved.multidevice.DeviceLink
|
import org.session.libsignal.service.loki.protocol.shelved.multidevice.DeviceLink
|
||||||
@ -18,7 +18,7 @@ import java.net.URL
|
|||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
|
|
||||||
class FileServerAPI(public val server: String, userPublicKey: String, userPrivateKey: ByteArray, private val database: LokiAPIDatabaseProtocol) : LokiDotNetAPI(userPublicKey, userPrivateKey, database) {
|
class FileServerAPI(public val server: String, userPublicKey: String, userPrivateKey: ByteArray, private val database: LokiAPIDatabaseProtocol) : DotNetAPI() {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
// region Settings
|
// region Settings
|
||||||
@ -49,6 +49,7 @@ class FileServerAPI(public val server: String, userPublicKey: String, userPrivat
|
|||||||
* possible after proof of work has been calculated and the onion request encryption has happened, which takes several seconds.
|
* 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 fileSizeORMultiplier = 2 // TODO: It should be possible to set this to 1.5?
|
||||||
|
val server = "https://file.getsession.org"
|
||||||
public val fileStorageBucketURL = "https://file-static.lokinet.org"
|
public val fileStorageBucketURL = "https://file-static.lokinet.org"
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
|
@ -1,6 +1,13 @@
|
|||||||
package org.session.libsession.messaging.jobs
|
package org.session.libsession.messaging.jobs
|
||||||
|
|
||||||
|
import nl.komponents.kovenant.Promise
|
||||||
|
import nl.komponents.kovenant.deferred
|
||||||
|
import org.session.libsession.messaging.sending_receiving.MessageReceiver
|
||||||
|
import org.session.libsession.messaging.sending_receiving.handle
|
||||||
|
import org.session.libsignal.libsignal.logging.Log
|
||||||
|
|
||||||
class MessageReceiveJob(val data: ByteArray, val isBackgroundPoll: Boolean, val openGroupMessageServerID: Long? = null, val openGroupID: String? = null) : Job {
|
class MessageReceiveJob(val data: ByteArray, val isBackgroundPoll: Boolean, val openGroupMessageServerID: Long? = null, val openGroupID: String? = null) : Job {
|
||||||
|
|
||||||
override var delegate: JobDelegate? = null
|
override var delegate: JobDelegate? = null
|
||||||
override var id: String? = null
|
override var id: String? = null
|
||||||
override var failureCount: Int = 0
|
override var failureCount: Int = 0
|
||||||
@ -8,10 +15,43 @@ class MessageReceiveJob(val data: ByteArray, val isBackgroundPoll: Boolean, val
|
|||||||
// Settings
|
// Settings
|
||||||
override val maxFailureCount: Int = 10
|
override val maxFailureCount: Int = 10
|
||||||
companion object {
|
companion object {
|
||||||
|
val TAG = MessageReceiveJob::class.qualifiedName
|
||||||
|
|
||||||
val collection: String = "MessageReceiveJobCollection"
|
val collection: String = "MessageReceiveJobCollection"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun execute() {
|
override fun execute() {
|
||||||
TODO("Not yet implemented")
|
exec()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun exec(): Promise<Unit, Exception> {
|
||||||
|
val deferred = deferred<Unit, Exception>()
|
||||||
|
try {
|
||||||
|
val (message, proto) = MessageReceiver.parse(this.data, this.openGroupMessageServerID)
|
||||||
|
MessageReceiver.handle(message, proto, this.openGroupID)
|
||||||
|
this.handleSuccess()
|
||||||
|
deferred.resolve(Unit)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.d(TAG, "Couldn't receive message due to error: $e.")
|
||||||
|
val error = e as? MessageReceiver.Error
|
||||||
|
error?.let {
|
||||||
|
if (!error.isRetryable) this.handlePermanentFailure(error)
|
||||||
|
}
|
||||||
|
this.handleFailure(e)
|
||||||
|
deferred.resolve(Unit) // The promise is just used to keep track of when we're done
|
||||||
|
}
|
||||||
|
return deferred.promise
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleSuccess() {
|
||||||
|
delegate?.handleJobSucceeded(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handlePermanentFailure(e: Exception) {
|
||||||
|
delegate?.handleJobFailedPermanently(this, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleFailure(e: Exception) {
|
||||||
|
delegate?.handleJobFailed(this, e)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,9 +1,15 @@
|
|||||||
package org.session.libsession.messaging.jobs
|
package org.session.libsession.messaging.jobs
|
||||||
|
|
||||||
|
import org.session.libsession.messaging.MessagingConfiguration
|
||||||
import org.session.libsession.messaging.messages.Destination
|
import org.session.libsession.messaging.messages.Destination
|
||||||
import org.session.libsession.messaging.messages.Message
|
import org.session.libsession.messaging.messages.Message
|
||||||
|
import org.session.libsession.messaging.messages.visible.VisibleMessage
|
||||||
|
import org.session.libsession.messaging.sending_receiving.MessageSender
|
||||||
|
import org.session.libsignal.libsignal.logging.Log
|
||||||
|
import org.session.libsignal.service.internal.push.SignalServiceProtos
|
||||||
|
|
||||||
class MessageSendJob(val message: Message, val destination: Destination) : Job {
|
class MessageSendJob(val message: Message, val destination: Destination) : Job {
|
||||||
|
|
||||||
override var delegate: JobDelegate? = null
|
override var delegate: JobDelegate? = null
|
||||||
override var id: String? = null
|
override var id: String? = null
|
||||||
override var failureCount: Int = 0
|
override var failureCount: Int = 0
|
||||||
@ -11,10 +17,54 @@ class MessageSendJob(val message: Message, val destination: Destination) : Job {
|
|||||||
// Settings
|
// Settings
|
||||||
override val maxFailureCount: Int = 10
|
override val maxFailureCount: Int = 10
|
||||||
companion object {
|
companion object {
|
||||||
|
val TAG = MessageSendJob::class.qualifiedName
|
||||||
|
|
||||||
val collection: String = "MessageSendJobCollection"
|
val collection: String = "MessageSendJobCollection"
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun execute() {
|
override fun execute() {
|
||||||
TODO("Not yet implemented")
|
val messageDataProvider = MessagingConfiguration.shared.messageDataProvider
|
||||||
|
val message = message as? VisibleMessage
|
||||||
|
message?.let {
|
||||||
|
if(!messageDataProvider.isOutgoingMessage(message.sentTimestamp!!)) return // The message has been deleted
|
||||||
|
val attachments = message.attachmentIDs.map { messageDataProvider.getAttachment(it) }.filterNotNull()
|
||||||
|
val attachmentsToUpload = attachments.filter { !it.isUploaded }
|
||||||
|
attachmentsToUpload.forEach {
|
||||||
|
if(MessagingConfiguration.shared.storage.getAttachmentUploadJob(it.attachmentId) != null) {
|
||||||
|
// Wait for it to finish
|
||||||
|
} else {
|
||||||
|
val job = AttachmentUploadJob(it.attachmentId, message.threadID!!, message, id!!)
|
||||||
|
JobQueue.shared.add(job)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (attachmentsToUpload.isNotEmpty()) return // Wait for all attachments to upload before continuing
|
||||||
|
}
|
||||||
|
MessageSender.send(this.message, this.destination).success {
|
||||||
|
this.handleSuccess()
|
||||||
|
}.fail { exception ->
|
||||||
|
Log.e(TAG, "Couldn't send message due to error: $exception.")
|
||||||
|
val e = exception as? MessageSender.Error
|
||||||
|
e?.let {
|
||||||
|
if (!e.isRetryable) this.handlePermanentFailure(e)
|
||||||
|
}
|
||||||
|
this.handleFailure(exception)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleSuccess() {
|
||||||
|
delegate?.handleJobSucceeded(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handlePermanentFailure(error: Exception) {
|
||||||
|
delegate?.handleJobFailedPermanently(this, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleFailure(error: Exception) {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
delegate?.handleJobFailed(this, error)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,7 +8,7 @@ class LinkPreview() {
|
|||||||
|
|
||||||
var title: String? = null
|
var title: String? = null
|
||||||
var url: String? = null
|
var url: String? = null
|
||||||
var attachmentID: String? = null
|
var attachmentID: Long? = 0
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "LinkPreview"
|
const val TAG = "LinkPreview"
|
||||||
@ -21,7 +21,7 @@ class LinkPreview() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//constructor
|
//constructor
|
||||||
internal constructor(title: String?, url: String, attachmentID: String?) : this() {
|
internal constructor(title: String?, url: String, attachmentID: Long?) : this() {
|
||||||
this.title = title
|
this.title = title
|
||||||
this.url = url
|
this.url = url
|
||||||
this.attachmentID = attachmentID
|
this.attachmentID = attachmentID
|
||||||
|
@ -11,7 +11,7 @@ class Quote() {
|
|||||||
var timestamp: Long? = 0
|
var timestamp: Long? = 0
|
||||||
var publicKey: String? = null
|
var publicKey: String? = null
|
||||||
var text: String? = null
|
var text: String? = null
|
||||||
var attachmentID: String? = null
|
var attachmentID: Long? = null
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val TAG = "Quote"
|
const val TAG = "Quote"
|
||||||
@ -25,7 +25,7 @@ class Quote() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//constructor
|
//constructor
|
||||||
internal constructor(timestamp: Long, publicKey: String, text: String?, attachmentID: String?) : this() {
|
internal constructor(timestamp: Long, publicKey: String, text: String?, attachmentID: Long?) : this() {
|
||||||
this.timestamp = timestamp
|
this.timestamp = timestamp
|
||||||
this.publicKey = publicKey
|
this.publicKey = publicKey
|
||||||
this.text = text
|
this.text = text
|
||||||
|
@ -11,7 +11,7 @@ import org.session.libsignal.service.internal.push.SignalServiceProtos
|
|||||||
class VisibleMessage : Message() {
|
class VisibleMessage : Message() {
|
||||||
|
|
||||||
var text: String? = null
|
var text: String? = null
|
||||||
var attachmentIDs = ArrayList<String>()
|
var attachmentIDs = ArrayList<Long>()
|
||||||
var quote: Quote? = null
|
var quote: Quote? = null
|
||||||
var linkPreview: LinkPreview? = null
|
var linkPreview: LinkPreview? = null
|
||||||
var contact: Contact? = null
|
var contact: Contact? = null
|
||||||
|
Loading…
Reference in New Issue
Block a user