fix(messagelogger): ui freezes & optimization

This commit is contained in:
rhunk
2023-05-31 17:27:25 +02:00
parent 25caf52dfe
commit cb55923fd8
8 changed files with 53 additions and 38 deletions

View File

@@ -71,7 +71,7 @@ abstract class AbstractBridgeClient {
* @param id the ID of the message logger message
* @return the content of the message
*/
abstract fun getMessageLoggerMessage(id: Long): ByteArray?
abstract fun getMessageLoggerMessage(conversationId: String, id: Long): ByteArray?
/**
* Add a message to the message logger database
@@ -79,14 +79,14 @@ abstract class AbstractBridgeClient {
* @param id the ID of the message logger message
* @param message the content of the message
*/
abstract fun addMessageLoggerMessage(id: Long, message: ByteArray)
abstract fun addMessageLoggerMessage(conversationId: String, id: Long, message: ByteArray)
/**
* Delete a message from the message logger database
*
* @param id the ID of the message logger message
*/
abstract fun deleteMessageLoggerMessage(id: Long)
abstract fun deleteMessageLoggerMessage(conversationId: String, id: Long)
/**
* Clear the message logger database

View File

@@ -12,33 +12,30 @@ class MessageLoggerWrapper(
fun init() {
database = SQLiteDatabase.openDatabase(databaseFile.absolutePath, null, SQLiteDatabase.CREATE_IF_NECESSARY or SQLiteDatabase.OPEN_READWRITE)
database.execSQL("CREATE TABLE IF NOT EXISTS messages (message_id INTEGER PRIMARY KEY, serialized_message BLOB)")
database.execSQL("CREATE TABLE IF NOT EXISTS messages (id INTEGER PRIMARY KEY, conversation_id VARCHAR, message_id BIGINT, message_data BLOB)")
}
fun deleteMessage(messageId: Long) {
database.execSQL("DELETE FROM messages WHERE message_id = ?", arrayOf(messageId.toString()))
fun deleteMessage(conversationId: String, messageId: Long) {
database.execSQL("DELETE FROM messages WHERE conversation_id = ? AND message_id = ?", arrayOf(conversationId, messageId.toString()))
}
fun addMessage(messageId: Long, serializedMessage: ByteArray): Boolean {
val cursor = database.rawQuery("SELECT message_id FROM messages WHERE message_id = ?", arrayOf(messageId.toString()))
fun addMessage(conversationId: String, messageId: Long, serializedMessage: ByteArray): Boolean {
val cursor = database.rawQuery("SELECT message_id FROM messages WHERE conversation_id = ? AND message_id = ?", arrayOf(conversationId, messageId.toString()))
val state = cursor.moveToFirst()
cursor.close()
if (state) {
return false
}
database.insert("messages", null, ContentValues().apply {
put("conversation_id", conversationId)
put("message_id", messageId)
put("serialized_message", serializedMessage)
put("message_data", serializedMessage)
})
return true
}
fun clearMessages() {
database.execSQL("DELETE FROM messages")
}
fun getMessage(messageId: Long): Pair<Boolean, ByteArray?> {
val cursor = database.rawQuery("SELECT serialized_message FROM messages WHERE message_id = ?", arrayOf(messageId.toString()))
fun getMessage(conversationId: String, messageId: Long): Pair<Boolean, ByteArray?> {
val cursor = database.rawQuery("SELECT message_data FROM messages WHERE conversation_id = ? AND message_id = ?", arrayOf(conversationId, messageId.toString()))
val state = cursor.moveToFirst()
val message: ByteArray? = if (state) {
cursor.getBlob(0)
@@ -48,4 +45,8 @@ class MessageLoggerWrapper(
cursor.close()
return Pair(state, message)
}
fun clearMessages() {
database.execSQL("DELETE FROM messages")
}
}

View File

@@ -65,20 +65,20 @@ class RootBridgeClient : AbstractBridgeClient() {
return true
}
override fun getMessageLoggerMessage(id: Long): ByteArray? {
val (state, messageData) = messageLoggerWrapper.getMessage(id)
override fun getMessageLoggerMessage(conversationId: String, id: Long): ByteArray? {
val (state, messageData) = messageLoggerWrapper.getMessage(conversationId, id)
if (state) {
return messageData
}
return null
}
override fun addMessageLoggerMessage(id: Long, message: ByteArray) {
messageLoggerWrapper.addMessage(id, message)
override fun addMessageLoggerMessage(conversationId: String, id: Long, message: ByteArray) {
messageLoggerWrapper.addMessage(conversationId, id, message)
}
override fun deleteMessageLoggerMessage(id: Long) {
messageLoggerWrapper.deleteMessage(id)
override fun deleteMessageLoggerMessage(conversationId: String, id: Long) {
messageLoggerWrapper.deleteMessage(conversationId, id)
}
override fun clearMessageLogger() {

View File

@@ -1,10 +1,12 @@
package me.rhunk.snapenhance.bridge.client
import android.annotation.TargetApi
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.HandlerThread
@@ -38,6 +40,7 @@ class ServiceBridgeClient: AbstractBridgeClient(), ServiceConnection {
private lateinit var messenger: Messenger
private lateinit var future: CompletableFuture<Boolean>
@TargetApi(Build.VERSION_CODES.Q)
override fun start(callback: (Boolean) -> Unit) {
this.future = CompletableFuture()
this.handlerThread.start()
@@ -174,28 +177,28 @@ class ServiceBridgeClient: AbstractBridgeClient(), ServiceConnection {
}
}
override fun getMessageLoggerMessage(id: Long): ByteArray? {
override fun getMessageLoggerMessage(conversationId: String, id: Long): ByteArray? {
sendMessage(
BridgeMessageType.MESSAGE_LOGGER_REQUEST,
MessageLoggerRequest(MessageLoggerRequest.Action.GET, id),
MessageLoggerRequest(MessageLoggerRequest.Action.GET, conversationId, id),
MessageLoggerResult::class
).run {
return message
}
}
override fun addMessageLoggerMessage(id: Long, message: ByteArray) {
override fun addMessageLoggerMessage(conversationId: String,id: Long, message: ByteArray) {
sendMessage(
BridgeMessageType.MESSAGE_LOGGER_REQUEST,
MessageLoggerRequest(MessageLoggerRequest.Action.ADD, id, message),
MessageLoggerRequest(MessageLoggerRequest.Action.ADD, conversationId, id, message),
MessageLoggerResult::class
)
}
override fun deleteMessageLoggerMessage(id: Long) {
override fun deleteMessageLoggerMessage(conversationId: String,id: Long) {
sendMessage(
BridgeMessageType.MESSAGE_LOGGER_REQUEST,
MessageLoggerRequest(MessageLoggerRequest.Action.DELETE, id),
MessageLoggerRequest(MessageLoggerRequest.Action.DELETE, conversationId, id),
MessageLoggerResult::class
)
}
@@ -203,7 +206,7 @@ class ServiceBridgeClient: AbstractBridgeClient(), ServiceConnection {
override fun clearMessageLogger() {
sendMessage(
BridgeMessageType.MESSAGE_LOGGER_REQUEST,
MessageLoggerRequest(MessageLoggerRequest.Action.CLEAR, 0),
MessageLoggerRequest(MessageLoggerRequest.Action.CLEAR),
MessageLoggerResult::class
)
}

View File

@@ -5,18 +5,21 @@ import me.rhunk.snapenhance.bridge.common.BridgeMessage
class MessageLoggerRequest(
var action: Action? = null,
var conversationId: String? = null,
var messageId: Long? = null,
var message: ByteArray? = null
) : BridgeMessage(){
override fun write(bundle: Bundle) {
bundle.putString("action", action!!.name)
bundle.putString("conversationId", conversationId)
bundle.putLong("messageId", messageId!!)
bundle.putByteArray("message", message)
}
override fun read(bundle: Bundle) {
action = Action.valueOf(bundle.getString("action")!!)
conversationId = bundle.getString("conversationId")
messageId = bundle.getLong("messageId")
message = bundle.getByteArray("message")
}

View File

@@ -82,7 +82,7 @@ class BridgeService : Service() {
private fun handleMessageLoggerRequest(msg: MessageLoggerRequest, reply: (Message) -> Unit) {
when (msg.action) {
MessageLoggerRequest.Action.ADD -> {
val isSuccess = messageLoggerWrapper.addMessage(msg.messageId!!, msg.message!!)
val isSuccess = messageLoggerWrapper.addMessage(msg.conversationId!!, msg.messageId!!, msg.message!!)
reply(MessageLoggerResult(isSuccess).toMessage(BridgeMessageType.MESSAGE_LOGGER_RESULT.value))
return
}
@@ -90,10 +90,10 @@ class BridgeService : Service() {
messageLoggerWrapper.clearMessages()
}
MessageLoggerRequest.Action.DELETE -> {
messageLoggerWrapper.deleteMessage(msg.messageId!!)
messageLoggerWrapper.deleteMessage(msg.conversationId!!, msg.messageId!!)
}
MessageLoggerRequest.Action.GET -> {
val (state, messageData) = messageLoggerWrapper.getMessage(msg.messageId!!)
val (state, messageData) = messageLoggerWrapper.getMessage(msg.conversationId!!, msg.messageId!!)
reply(MessageLoggerResult(state, messageData).toMessage(BridgeMessageType.MESSAGE_LOGGER_RESULT.value))
}
else -> {

View File

@@ -10,14 +10,19 @@ import me.rhunk.snapenhance.features.FeatureLoadParams
import me.rhunk.snapenhance.hook.HookStage
import me.rhunk.snapenhance.hook.Hooker
class MessageLogger : Feature("MessageLogger", loadParams = FeatureLoadParams.INIT_SYNC or FeatureLoadParams.ACTIVITY_CREATE_SYNC) {
class MessageLogger : Feature("MessageLogger", loadParams = FeatureLoadParams.INIT_SYNC or FeatureLoadParams.ACTIVITY_CREATE_ASYNC) {
private val messageCache = mutableMapOf<Long, String>()
private val removedMessages = linkedSetOf<Long>()
private val myUserId by lazy { context.database.getMyUserId() }
fun isMessageRemoved(messageId: Long) = removedMessages.contains(messageId)
override fun onActivityCreate() {
fun deleteMessage(conversationId: String, messageId: Long) {
messageCache.remove(messageId)
context.bridgeClient.deleteMessageLoggerMessage(conversationId, messageId)
}
override fun asyncOnActivityCreate() {
if (!context.database.hasArroyo()) {
context.bridgeClient.clearMessageLogger()
}
@@ -31,15 +36,15 @@ class MessageLogger : Feature("MessageLogger", loadParams = FeatureLoadParams.IN
val message = Message(it.thisObject())
val messageId = message.messageDescriptor.messageId
val contentType = message.messageContent.contentType
val conversationId = message.messageDescriptor.conversationId.toString()
val messageState = message.messageState
if (messageState != MessageState.COMMITTED) return@hookConstructor
if (contentType == ContentType.STATUS) {
//query the deleted message
val deletedMessage: String = if (messageCache.containsKey(messageId)) messageCache[messageId] else {
context.bridgeClient.getMessageLoggerMessage(messageId)?.toString(Charsets.UTF_8)
context.bridgeClient.getMessageLoggerMessage(conversationId, messageId)?.toString(Charsets.UTF_8)
} ?: return@hookConstructor
val messageJsonObject = JsonParser.parseString(deletedMessage).asJsonObject
@@ -72,10 +77,10 @@ class MessageLogger : Feature("MessageLogger", loadParams = FeatureLoadParams.IN
if (!messageCache.containsKey(messageId)) {
context.executeAsync {
val storedMessage = context.bridgeClient.getMessageLoggerMessage(messageId)?.toString(Charsets.UTF_8)
val storedMessage = context.bridgeClient.getMessageLoggerMessage(conversationId, messageId)?.toString(Charsets.UTF_8)
if (storedMessage == null) {
messageCache[messageId] = context.gson.toJson(message.instanceNonNull())
context.bridgeClient.addMessageLoggerMessage(messageId, messageCache[messageId]!!.toByteArray(Charsets.UTF_8))
context.bridgeClient.addMessageLoggerMessage(conversationId, messageId, messageCache[messageId]!!.toByteArray(Charsets.UTF_8))
return@executeAsync
}
messageCache[messageId] = storedMessage

View File

@@ -15,6 +15,7 @@ import me.rhunk.snapenhance.Constants.VIEW_INJECTED_CODE
import me.rhunk.snapenhance.config.ConfigProperty
import me.rhunk.snapenhance.features.impl.Messaging
import me.rhunk.snapenhance.features.impl.downloader.MediaDownloader
import me.rhunk.snapenhance.features.impl.spying.MessageLogger
import me.rhunk.snapenhance.features.impl.ui.menus.AbstractMenu
@@ -94,7 +95,9 @@ class ChatActionMenu : AbstractMenu() {
downloadButton.setOnClickListener {
closeActionMenu()
context.executeAsync {
context.bridgeClient.deleteMessageLoggerMessage(context.feature(Messaging::class).lastFocusedMessageId)
with(context.feature(Messaging::class)) {
context.feature(MessageLogger::class).deleteMessage(lastOpenedConversationUUID.toString(), lastFocusedMessageId)
}
}
}
parent.addView(downloadButton)