Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ca1e7b7c authored by Moez Bhatti's avatar Moez Bhatti
Browse files

Improve message sync speed & reliability

parent bc6c19e0
Loading
Loading
Loading
Loading
+0 −2
Original line number Diff line number Diff line
@@ -124,8 +124,6 @@ class CursorToMessageImpl @Inject constructor(
                            ?.let { EncodedStringValue(subjectCharset, it).string } ?: ""
                    textContentType = ""
                    attachmentType = Message.AttachmentType.NOT_LOADED

                    parts.addAll(cursorToPart.getPartsCursor(contentId)?.map { cursorToPart.map(it) } ?: listOf())
                }
            }
        }
+4 −4
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ class CursorToPartImpl @Inject constructor(private val context: Context) : Curso

    override fun map(from: Cursor) = MmsPart().apply {
        id = from.getLong(from.getColumnIndexOrThrow(Telephony.Mms.Part._ID))
        messageId = from.getLong(from.getColumnIndexOrThrow(Telephony.Mms.Part.MSG_ID))
        type = from.getStringOrNull(from.getColumnIndexOrThrow(Telephony.Mms.Part.CONTENT_TYPE)) ?: "*/*"
        seq = from.getIntOrNull(from.getColumnIndexOrThrow(Telephony.Mms.Part.SEQ)) ?: -1
        name = from.getStringOrNull(from.getColumnIndexOrThrow(Telephony.Mms.Part.NAME))
@@ -43,9 +44,8 @@ class CursorToPartImpl @Inject constructor(private val context: Context) : Curso
        text = from.getStringOrNull(from.getColumnIndexOrThrow(Telephony.Mms.Part.TEXT))
    }

    override fun getPartsCursor(messageId: Long): Cursor? {
        return context.contentResolver.query(CONTENT_URI, null,
                "${Telephony.Mms.Part.MSG_ID} = ?", arrayOf(messageId.toString()), null)
    override fun getPartsCursor(): Cursor? {
        return context.contentResolver.query(CONTENT_URI, null, null, null, null)
    }

}
+12 −1
Original line number Diff line number Diff line
@@ -36,7 +36,7 @@ class QkRealmMigration @Inject constructor(
) : RealmMigration {

    companion object {
        const val SchemaVersion: Long = 10
        const val SchemaVersion: Long = 11
    }

    @SuppressLint("ApplySharedPref")
@@ -223,6 +223,17 @@ class QkRealmMigration @Inject constructor(
            version++
        }

        if (version == 10L) {
            realm.schema.get("MmsPart")
                    ?.addField("messageId", Long::class.java, FieldAttribute.INDEXED, FieldAttribute.REQUIRED)
                    ?.transform { part ->
                        val messageId = part.linkingObjects("Message", "parts").firstOrNull()?.getLong("contentId") ?: 0
                        part.setLong("messageId", messageId)
                    }

            version++
        }

        check(version >= newVersion) { "Migration missing from v$oldVersion to v$newVersion" }
    }

+60 −35
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.content.ContentUris
import android.net.Uri
import android.provider.Telephony
import com.f2prateek.rx.preferences2.RxSharedPreferences
import com.moez.QKSMS.extensions.forEach
import com.moez.QKSMS.extensions.insertOrUpdate
import com.moez.QKSMS.extensions.map
import com.moez.QKSMS.manager.KeyManager
@@ -31,6 +32,7 @@ import com.moez.QKSMS.mapper.CursorToContactGroup
import com.moez.QKSMS.mapper.CursorToContactGroupMember
import com.moez.QKSMS.mapper.CursorToConversation
import com.moez.QKSMS.mapper.CursorToMessage
import com.moez.QKSMS.mapper.CursorToPart
import com.moez.QKSMS.mapper.CursorToRecipient
import com.moez.QKSMS.model.Contact
import com.moez.QKSMS.model.ContactGroup
@@ -45,6 +47,7 @@ import com.moez.QKSMS.util.tryOrNull
import io.reactivex.subjects.BehaviorSubject
import io.reactivex.subjects.Subject
import io.realm.Realm
import io.realm.RealmList
import io.realm.Sort
import javax.inject.Inject
import javax.inject.Singleton
@@ -55,6 +58,7 @@ class SyncRepositoryImpl @Inject constructor(
    private val conversationRepo: ConversationRepository,
    private val cursorToConversation: CursorToConversation,
    private val cursorToMessage: CursorToMessage,
    private val cursorToPart: CursorToPart,
    private val cursorToRecipient: CursorToRecipient,
    private val cursorToContact: CursorToContact,
    private val cursorToContactGroup: CursorToContactGroup,
@@ -103,25 +107,48 @@ class SyncRepositoryImpl @Inject constructor(

        keys.reset()

        val partsCursor = cursorToPart.getPartsCursor()
        val messageCursor = cursorToMessage.getMessagesCursor()
        val conversationCursor = cursorToConversation.getConversationsCursor()
        val recipientCursor = cursorToRecipient.getRecipientCursor()

        val max = (messageCursor?.count ?: 0) +
        val max = (partsCursor?.count ?: 0) +
                (messageCursor?.count ?: 0) +
                (conversationCursor?.count ?: 0) +
                (recipientCursor?.count ?: 0)

        var progress = 0

        // Sync message parts
        partsCursor?.use {
            partsCursor.forEach {
                tryOrNull {
                    progress++
                    val part = cursorToPart.map(partsCursor)
                    realm.insertOrUpdate(part)
                }
            }
        }

        // Sync messages
        messageCursor?.use {
            val messageColumns = CursorToMessage.MessageColumns(messageCursor)
            val messages = messageCursor.map { cursor ->
            messageCursor.forEach { cursor ->
                tryOrNull {
                    progress++
                    syncProgress.onNext(SyncRepository.SyncProgress.Running(max, progress, false))
                cursorToMessage.map(Pair(cursor, messageColumns))
                    val message = cursorToMessage.map(Pair(cursor, messageColumns)).apply {
                        if (isMms()) {
                            parts = RealmList<MmsPart>().apply {
                                addAll(realm.where(MmsPart::class.java)
                                        .equalTo("messageId", contentId)
                                        .findAll())
                            }
                        }
                    }
                    realm.insertOrUpdate(message)
                }
            }
            realm.insertOrUpdate(messages)
        }

        // Migrate blocked conversations from 2.7.3
@@ -133,10 +160,11 @@ class SyncRepositoryImpl @Inject constructor(

        // Sync conversations
        conversationCursor?.use {
            val conversations = conversationCursor.map { cursor ->
            conversationCursor.forEach { cursor ->
                tryOrNull {
                    progress++
                    syncProgress.onNext(SyncRepository.SyncProgress.Running(max, progress, false))
                cursorToConversation.map(cursor).apply {
                    val conversation = cursorToConversation.map(cursor).apply {
                        persistedData[id]?.let { persistedConversation ->
                            archived = persistedConversation.archived
                            blocked = persistedConversation.blocked
@@ -145,34 +173,31 @@ class SyncRepositoryImpl @Inject constructor(
                            blockingClient = persistedConversation.blockingClient
                            blockReason = persistedConversation.blockReason
                        }
                        lastMessage = realm.where(Message::class.java)
                                .sort("date", Sort.DESCENDING)
                                .equalTo("threadId", id)
                                .findFirst()
                    }
                    realm.insertOrUpdate(conversation)
                }

            realm.where(Message::class.java)
                    .sort("date", Sort.DESCENDING)
                    .distinct("threadId")
                    .findAll()
                    .forEach { message ->
                        val conversation = conversations.find { conversation -> conversation.id == message.threadId }
                        conversation?.lastMessage = message
            }

            realm.insertOrUpdate(conversations)
        }

        // Sync recipients
        recipientCursor?.use {
            val contacts = realm.copyToRealmOrUpdate(getContacts())
            val recipients = recipientCursor.map { cursor ->
            recipientCursor.forEach { cursor ->
                tryOrNull {
                    progress++
                    syncProgress.onNext(SyncRepository.SyncProgress.Running(max, progress, false))
                cursorToRecipient.map(cursor).apply {
                    val recipient = cursorToRecipient.map(cursor).apply {
                        contact = contacts.firstOrNull { contact ->
                            contact.numbers.any { phoneNumberUtils.compare(address, it.address) }
                        }
                    }
                    realm.insertOrUpdate(recipient)
                }
            }
            realm.insertOrUpdate(recipients)
        }

        syncProgress.onNext(SyncRepository.SyncProgress.Running(0, 0, true))
+2 −2
Original line number Diff line number Diff line
@@ -23,6 +23,6 @@ import com.moez.QKSMS.model.MmsPart

interface CursorToPart : Mapper<Cursor, MmsPart> {

    fun getPartsCursor(messageId: Long): Cursor?
    fun getPartsCursor(): Cursor?

}
Loading