fix(messagelogger): ui freezes & optimization
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
@@ -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
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
@@ -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 -> {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user