summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Li <pyli@google.com>2021-11-11 20:16:42 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-11-11 20:16:42 +0000
commit5985d9a860bbb7cd2113dbcf7268ab1811a53b72 (patch)
tree7df04ebce46b59bbf3e9530e42679fc53bd32b66
parent6188fde28eab406b5c5da698c1df51d315345fd6 (diff)
parentc7df51807e792be10bd477a4930b4dec633dcad6 (diff)
downloadMessenger-5985d9a860bbb7cd2113dbcf7268ab1811a53b72.tar.gz
Fix receiving old text message in HUN am: c7df51807e
Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Car/Messenger/+/16240952 Change-Id: Ia0bc9f3a1751f061040bdf2193794b538e516384
-rw-r--r--src/com/android/car/messenger/impl/datamodels/NewMessageLiveData.java2
-rw-r--r--src/com/android/car/messenger/impl/datamodels/util/ConversationFetchUtil.java26
-rw-r--r--src/com/android/car/messenger/impl/datamodels/util/CursorUtils.java22
-rw-r--r--src/com/android/car/messenger/impl/datamodels/util/MessageUtils.java100
4 files changed, 103 insertions, 47 deletions
diff --git a/src/com/android/car/messenger/impl/datamodels/NewMessageLiveData.java b/src/com/android/car/messenger/impl/datamodels/NewMessageLiveData.java
index f725418..a5e0922 100644
--- a/src/com/android/car/messenger/impl/datamodels/NewMessageLiveData.java
+++ b/src/com/android/car/messenger/impl/datamodels/NewMessageLiveData.java
@@ -65,7 +65,7 @@ public class NewMessageLiveData extends ContentProviderLiveData<Conversation> {
private final CarStateListener mCarStateListener = AppFactory.get().getCarStateListener();
NewMessageLiveData() {
- super(Telephony.Sms.CONTENT_URI, Telephony.Mms.CONTENT_URI, Telephony.MmsSms.CONTENT_URI);
+ super(Telephony.MmsSms.CONTENT_URI);
}
@Override
diff --git a/src/com/android/car/messenger/impl/datamodels/util/ConversationFetchUtil.java b/src/com/android/car/messenger/impl/datamodels/util/ConversationFetchUtil.java
index 5cea752..b066417 100644
--- a/src/com/android/car/messenger/impl/datamodels/util/ConversationFetchUtil.java
+++ b/src/com/android/car/messenger/impl/datamodels/util/ConversationFetchUtil.java
@@ -55,17 +55,25 @@ public class ConversationFetchUtil {
public static Conversation fetchConversation(@NonNull String conversationId) {
L.d("Fetching latest data for Conversation " + conversationId);
Conversation.Builder conversationBuilder = initConversationBuilder(conversationId);
- Cursor messagesCursor =
- CursorUtils.getMessagesCursor(conversationId, MESSAGE_LIMIT, /* offset= */ 0);
+ Cursor mmsCursor = getMmsCursor(conversationId);
+ Cursor smsCursor = getSmsCursor(conversationId);
+
+ // message list sorted by date desc
+ List<Conversation.Message> messages =
+ MessageUtils.getMessages(MESSAGE_LIMIT, mmsCursor, smsCursor);
+
// messages to read: first get unread messages
- List<Conversation.Message> messagesToRead = MessageUtils.getUnreadMessages(messagesCursor);
+ // List should truncate at the latest reply or read message since reading a recent message
+ // does not mark all previous messages read.
+ List<Conversation.Message> messagesToRead = MessageUtils.getUnreadMessages(messages);
+
int unreadCount = messagesToRead.size();
Conversation.Message lastReply = null;
// if no unread messages, get read messages
if (messagesToRead.isEmpty()) {
Pair<List<Conversation.Message>, Conversation.Message> readMessagesAndReplyTimestamp =
- MessageUtils.getReadMessagesAndReplyTimestamp(messagesCursor);
+ MessageUtils.getReadMessagesAndReplyTimestamp(messages);
messagesToRead = readMessagesAndReplyTimestamp.first;
lastReply = readMessagesAndReplyTimestamp.second;
}
@@ -152,4 +160,14 @@ public class ConversationFetchUtil {
return sharedPreferences.getStringSet(
MessageConstants.KEY_MUTED_CONVERSATIONS, new HashSet<>());
}
+
+ private static Cursor getMmsCursor(@NonNull String conversationId) {
+ return CursorUtils.getMessagesCursor(
+ conversationId, MESSAGE_LIMIT, /* offset= */ 0, CursorUtils.ContentType.MMS);
+ }
+
+ private static Cursor getSmsCursor(@NonNull String conversationId) {
+ return CursorUtils.getMessagesCursor(
+ conversationId, MESSAGE_LIMIT, /* offset= */ 0, CursorUtils.ContentType.SMS);
+ }
}
diff --git a/src/com/android/car/messenger/impl/datamodels/util/CursorUtils.java b/src/com/android/car/messenger/impl/datamodels/util/CursorUtils.java
index 5ce2302..93b6a85 100644
--- a/src/com/android/car/messenger/impl/datamodels/util/CursorUtils.java
+++ b/src/com/android/car/messenger/impl/datamodels/util/CursorUtils.java
@@ -28,6 +28,8 @@ import static android.provider.Telephony.ThreadsColumns.DATE;
import static android.provider.Telephony.ThreadsColumns.READ;
import static android.provider.Telephony.ThreadsColumns.RECIPIENT_IDS;
+import static com.android.car.messenger.impl.datamodels.util.MmsUtils.MMS_CONTENT_TYPE;
+
import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
@@ -59,6 +61,16 @@ public class CursorUtils {
@NonNull
public static final String DEFAULT_SORT_ORDER = Telephony.TextBasedSmsColumns.DATE + " DESC";
+ private static final String MMS_QUERY =
+ CONTENT_TYPE + " = '" + MMS_CONTENT_TYPE + "' AND " + DATE + " > ";
+ private static final String SMS_QUERY = CONTENT_TYPE + " IS NULL AND " + DATE + " > ";
+
+ /** This enum is used for describing the type of message being fetched by a cursor */
+ public enum ContentType {
+ SMS,
+ MMS
+ }
+
/**
* Get simplified thread cursor with metadata information on the thread, such as recipient ids
*/
@@ -82,13 +94,19 @@ public class CursorUtils {
* @param offset The starting point in timestamp in millisecond to fetch for data
*/
@Nullable
- public static Cursor getMessagesCursor(@NonNull String conversationId, int limit, long offset) {
+ public static Cursor getMessagesCursor(@NonNull String conversationId, int limit, long offset,
+ @NonNull ContentType contentType) {
Context context = AppFactory.get().getContext();
ContentResolver contentResolver = context.getContentResolver();
+
+ String query = contentType == ContentType.MMS
+ ? MMS_QUERY + offset / 1000
+ : SMS_QUERY + offset;
+
return contentResolver.query(
getConversationUri(conversationId),
CONTENT_CONVERSATION_PROJECTION,
- DATE + " > " + offset,
+ query,
/* selectionArgs= */ null,
DEFAULT_SORT_ORDER + " LIMIT " + limit);
}
diff --git a/src/com/android/car/messenger/impl/datamodels/util/MessageUtils.java b/src/com/android/car/messenger/impl/datamodels/util/MessageUtils.java
index 555d91c..0bb454b 100644
--- a/src/com/android/car/messenger/impl/datamodels/util/MessageUtils.java
+++ b/src/com/android/car/messenger/impl/datamodels/util/MessageUtils.java
@@ -20,6 +20,7 @@ import static com.android.car.messenger.common.Conversation.Message.MessageStatu
import static com.android.car.messenger.common.Conversation.Message.MessageStatus.MESSAGE_STATUS_READ;
import static com.android.car.messenger.common.Conversation.Message.MessageStatus.MESSAGE_STATUS_UNREAD;
+import static java.lang.Math.min;
import static java.util.Comparator.comparingLong;
import android.content.Context;
@@ -47,61 +48,80 @@ import java.util.function.Function;
public final class MessageUtils {
/**
- * Gets all unread messages in cursor
+ * Returns all messages in the given cursors.
*
- * @param messagesCursor The messageCursor in descending order
+ * @param limit The maximum number of messages
+ * @param messageCursors The messageCursors of messages in descending order
*/
@NonNull
- public static List<Message> getUnreadMessages(@Nullable Cursor messagesCursor) {
- List<Message> unreadMessages = new ArrayList<>();
- MessageUtils.forEachDesc(
- messagesCursor,
- message -> {
- if (message.getMessageStatus() == MessageStatus.MESSAGE_STATUS_UNREAD) {
- unreadMessages.add(message);
+ public static List<Message> getMessages(int limit, @Nullable Cursor... messageCursors) {
+ List<Message> messages = new ArrayList<>();
+ for (Cursor cursor : messageCursors) {
+ MessageUtils.forEachDesc(
+ cursor,
+ message -> {
+ messages.add(message);
return true;
- }
- return false;
- });
- unreadMessages.sort(comparingLong(Message::getTimestamp));
+ });
+ }
+ messages.sort(comparingLong(Message::getTimestamp).reversed());
+ return messages.subList(0, min(limit, messages.size()));
+ }
+
+ /**
+ * Returns unread messages from a conversation, in ascending order.
+ *
+ * @param messages The messages in descending order
+ */
+ @NonNull
+ public static List<Message> getUnreadMessages(@NonNull List<Message> messages) {
+ int i = 0;
+ for (Conversation.Message message : messages) {
+ if (message.getMessageStatus() != MessageStatus.MESSAGE_STATUS_UNREAD) {
+ break;
+ }
+ i++;
+ }
+ List<Message> unreadMessages = messages.subList(0, i);
+ unreadMessages.sort(comparingLong(Conversation.Message::getTimestamp));
return unreadMessages;
}
+
/**
* Gets Read Messages and Last Reply
*
- * @param messagesCursor MessageCursor in descending order
+ * @param messages List of messages in descending order
*/
@NonNull
public static Pair<List<Message>, Message> getReadMessagesAndReplyTimestamp(
- @Nullable Cursor messagesCursor) {
+ @Nullable List<Message> messages) {
List<Message> readMessages = new ArrayList<>();
AtomicReference<Message> replyMessage = new AtomicReference<>();
AtomicReference<Long> lastReply = new AtomicReference<>(0L);
- MessageUtils.forEachDesc(
- messagesCursor,
- message -> {
- // Desired impact: 4. Reply -> 3. Messages -> 2. Reply -> 1 Messages (stop
- // parsing at 2.)
- // lastReply references 4., messages references 3.
- // Desired impact: 3. Messages -> 2. Reply -> 1. Messages (stop parsing at 2.)
- // lastReply references 2., messages references 3.
- int messageStatus = message.getMessageStatus();
- if (message.getMessageType() == MessageType.MESSAGE_TYPE_SENT) {
- if (lastReply.get() < message.getTimestamp()) {
- lastReply.set(message.getTimestamp());
- replyMessage.set(message);
- }
- return readMessages.isEmpty();
- }
-
- if (messageStatus == MessageStatus.MESSAGE_STATUS_READ
- || messageStatus == MessageStatus.MESSAGE_STATUS_NONE) {
- readMessages.add(message);
- return true;
- }
- return false;
- });
+
+ for (Message message : messages) {
+ // Desired impact: 4. Reply -> 3. Messages -> 2. Reply -> 1 Messages (stop
+ // parsing at 2.)
+ // lastReply references 4., messages references 3.
+ // Desired impact: 3. Messages -> 2. Reply -> 1. Messages (stop parsing at 2.)
+ // lastReply references 2., messages references 3.
+ int messageStatus = message.getMessageStatus();
+ if (message.getMessageType() == MessageType.MESSAGE_TYPE_SENT) {
+ if (lastReply.get() < message.getTimestamp()) {
+ lastReply.set(message.getTimestamp());
+ replyMessage.set(message);
+ }
+ if (!readMessages.isEmpty()) {
+ break;
+ }
+ } else if (messageStatus == MessageStatus.MESSAGE_STATUS_READ
+ || messageStatus == MessageStatus.MESSAGE_STATUS_NONE) {
+ readMessages.add(message);
+ } else {
+ break;
+ }
+ }
readMessages.sort(comparingLong(Message::getTimestamp));
return new Pair<>(readMessages, replyMessage.get());
}
@@ -113,7 +133,7 @@ public final class MessageUtils {
* @param processor A consumer that takes in the {@link Message} and returns true for the method
* to continue parsing the cursor or false to return.
*/
- public static void forEachDesc(
+ private static void forEachDesc(
@Nullable Cursor messageCursor, @NonNull Function<Message, Boolean> processor) {
if (messageCursor == null || !messageCursor.moveToFirst()) {
return;