From 0289416345d3862275f26a13527bbfc55957a1f3 Mon Sep 17 00:00:00 2001 From: Simon Redman Date: Mon, 15 May 2023 16:38:38 -0600 Subject: [PATCH] Initialize mostRecentTimestamp in SMSPlugin constructor --- src/org/kde/kdeconnect/Helpers/SMSHelper.java | 21 ++++++++ .../kde/kdeconnect/Helpers/ThreadHelper.kt | 4 -- .../Plugins/SMSPlugin/SMSPlugin.java | 53 ++++++++++--------- 3 files changed, 49 insertions(+), 29 deletions(-) diff --git a/src/org/kde/kdeconnect/Helpers/SMSHelper.java b/src/org/kde/kdeconnect/Helpers/SMSHelper.java index 533775f7..b74f75ef 100644 --- a/src/org/kde/kdeconnect/Helpers/SMSHelper.java +++ b/src/org/kde/kdeconnect/Helpers/SMSHelper.java @@ -127,6 +127,27 @@ public class SMSHelper { return Telephony.MmsSms.TYPE_DISCRIMINATOR_COLUMN; } + /** + * Get the timestamp of the newest known message. Will return Integer.MIN_VALUE if there are no messages. + * + * @param context android.content.Context running the request + * @return Timestamp of the oldest known message. + */ + public static @Nullable long getNewestMessageTimestamp( + @NonNull Context context + ) { + long oldestMessageTimestamp = Long.MIN_VALUE; + List newestMessage = SMSHelper.getMessagesInRange(context, null, Long.MAX_VALUE, 1l, true); + // There should only be one, but in case for some reason there are more, take the latest + for (SMSHelper.Message message : newestMessage) { + if (message != null && message.date > oldestMessageTimestamp) { + oldestMessageTimestamp = message.date; + } + } + + return oldestMessageTimestamp; + } + /** * Get some or all the messages in a requested thread, starting with the most-recent message * diff --git a/src/org/kde/kdeconnect/Helpers/ThreadHelper.kt b/src/org/kde/kdeconnect/Helpers/ThreadHelper.kt index 1442eb55..a1839be1 100644 --- a/src/org/kde/kdeconnect/Helpers/ThreadHelper.kt +++ b/src/org/kde/kdeconnect/Helpers/ThreadHelper.kt @@ -15,8 +15,4 @@ object ThreadHelper { @JvmStatic fun execute(command: Runnable) = executor.execute(command) - - @JvmStatic - fun executeCallable(callable: Callable): Future = executor.submit(callable) - } diff --git a/src/org/kde/kdeconnect/Plugins/SMSPlugin/SMSPlugin.java b/src/org/kde/kdeconnect/Plugins/SMSPlugin/SMSPlugin.java index ce3e5e6a..df08fec4 100644 --- a/src/org/kde/kdeconnect/Plugins/SMSPlugin/SMSPlugin.java +++ b/src/org/kde/kdeconnect/Plugins/SMSPlugin/SMSPlugin.java @@ -30,6 +30,7 @@ import android.telephony.PhoneNumberUtils; import android.telephony.SmsManager; import android.telephony.SmsMessage; +import androidx.annotation.WorkerThread; import androidx.annotation.NonNull; import androidx.core.content.ContextCompat; @@ -222,6 +223,13 @@ public class SMSPlugin extends Plugin { // thread, make sure that access is coherent private final Lock mostRecentTimestampLock = new ReentrantLock(); + /** + * Keep track of whether we have received any packet which requested messages. + * + * If not, we will not send updates, since probably the user doesn't care. + */ + private boolean haveMessagesBeenRequested = false; + private class MessageContentObserver extends ContentObserver { /** @@ -266,16 +274,18 @@ public class SMSPlugin extends Plugin { /** * Helper method to read the latest message from the sms-mms database and sends it to the desktop + * + * Should only be called after initializing the mostRecentTimestamp */ private void sendLatestMessage() { // Lock so no one uses the mostRecentTimestamp between the moment we read it and the // moment we update it. This is because reading the Messages DB can take long. mostRecentTimestampLock.lock(); - if (mostRecentTimestamp == 0) { - // Since the timestamp has not been initialized, we know that nobody else - // has requested a message. That being the case, there is most likely - // nobody listening for message updates, so just drop them + if (!haveMessagesBeenRequested) { + // Since the user has not requested a message, there is most likely nobody listening + // for message updates, so just drop them rather than spending battery/time sending + // updates that don't matter. mostRecentTimestampLock.unlock(); return; } @@ -375,6 +385,10 @@ public class SMSPlugin extends Plugin { // To see debug messages for Klinker library, uncomment the below line //Log.setDebug(true); + mostRecentTimestampLock.lock(); + mostRecentTimestamp = SMSHelper.getNewestMessageTimestamp(context); + mostRecentTimestampLock.unlock(); + return true; } @@ -394,12 +408,15 @@ public class SMSPlugin extends Plugin { switch (np.getType()) { case PACKET_TYPE_SMS_REQUEST_CONVERSATIONS: - Callable callable = () -> this.handleRequestAllConversations(np); - ThreadHelper.executeCallable(callable); + Runnable handleRequestAllConversationsRunnable = () -> this.handleRequestAllConversations(np); + ThreadHelper.execute(handleRequestAllConversationsRunnable); return true; case PACKET_TYPE_SMS_REQUEST_CONVERSATION: - return this.handleRequestSingleConversation(np); + Runnable handleRequestSingleConversationRunnable = () -> this.handleRequestSingleConversation(np); + ThreadHelper.execute(handleRequestSingleConversationRunnable); + return true; + case PACKET_TYPE_SMS_REQUEST: String textMessage = np.getString("messageBody"); subID = np.getLong("subID", -1); @@ -491,25 +508,22 @@ public class SMSPlugin extends Plugin { *

* Send one packet of type PACKET_TYPE_SMS_MESSAGE with the first message in all conversations */ + @WorkerThread private boolean handleRequestAllConversations(NetworkPacket packet) { + haveMessagesBeenRequested = true; Iterable conversations = SMSHelper.getConversations(this.context); - // Prepare the mostRecentTimestamp counter based on these messages, since they are the most - // recent in every conversation - mostRecentTimestampLock.lock(); for (SMSHelper.Message message : conversations) { - if (message.date > mostRecentTimestamp) { - mostRecentTimestamp = message.date; - } NetworkPacket partialReply = constructBulkMessagePacket(Collections.singleton(message)); device.sendPacket(partialReply); } - mostRecentTimestampLock.unlock(); return true; } + @WorkerThread private boolean handleRequestSingleConversation(NetworkPacket packet) { + haveMessagesBeenRequested = true; SMSHelper.ThreadID threadID = new SMSHelper.ThreadID(packet.getLong("threadID")); long rangeStartTimestamp = packet.getLong("rangeStartTimestamp", -1); @@ -526,17 +540,6 @@ public class SMSPlugin extends Plugin { conversation = SMSHelper.getMessagesInRange(this.context, threadID, rangeStartTimestamp, numberToGet, true); } - // Sometimes when desktop app is kept open while android app is restarted for any reason - // mostRecentTimeStamp must be updated in that scenario too if a user request for a - // single conversation and not the entire conversation list - mostRecentTimestampLock.lock(); - for (SMSHelper.Message message : conversation) { - if (message.date > mostRecentTimestamp) { - mostRecentTimestamp = message.date; - } - } - mostRecentTimestampLock.unlock(); - NetworkPacket reply = constructBulkMessagePacket(conversation); device.sendPacket(reply);