MessageQueue: Process pending messages per subscription am: 91abcc6c8e am: 5bf10fc9aa

Change-Id: Ie5e2f8996747896e098a8a2a2dddc4a87c0b668c
This commit is contained in:
Diogo Ferreira
2020-02-14 00:46:14 +00:00
@@ -24,12 +24,14 @@ import android.net.ConnectivityManager;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import android.telephony.ServiceState; import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import com.android.messaging.Factory; import com.android.messaging.Factory;
import com.android.messaging.datamodel.BugleDatabaseOperations; import com.android.messaging.datamodel.BugleDatabaseOperations;
import com.android.messaging.datamodel.DataModel; import com.android.messaging.datamodel.DataModel;
import com.android.messaging.datamodel.DatabaseHelper; import com.android.messaging.datamodel.DatabaseHelper;
import com.android.messaging.datamodel.DatabaseHelper.MessageColumns; import com.android.messaging.datamodel.DatabaseHelper.MessageColumns;
import com.android.messaging.datamodel.DatabaseHelper.ParticipantColumns;
import com.android.messaging.datamodel.DatabaseWrapper; import com.android.messaging.datamodel.DatabaseWrapper;
import com.android.messaging.datamodel.MessagingContentProvider; import com.android.messaging.datamodel.MessagingContentProvider;
import com.android.messaging.datamodel.data.MessageData; import com.android.messaging.datamodel.data.MessageData;
@@ -45,6 +47,7 @@ import com.android.messaging.util.OsUtil;
import com.android.messaging.util.PhoneUtils; import com.android.messaging.util.PhoneUtils;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
/** /**
@@ -218,13 +221,15 @@ public class ProcessPendingMessagesAction extends Action implements Parcelable {
final DatabaseWrapper db = DataModel.get().getDatabase(); final DatabaseWrapper db = DataModel.get().getDatabase();
final long now = System.currentTimeMillis(); final long now = System.currentTimeMillis();
final String toSendMessageId = findNextMessageToSend(db, now); for (int subId : getActiveSubscriptionIds()) {
if (toSendMessageId != null) { final String toSendMessageId = findNextMessageToSend(db, now, subId);
return true; if (toSendMessageId != null) {
} else {
final String toDownloadMessageId = findNextMessageToDownload(db, now);
if (toDownloadMessageId != null) {
return true; return true;
} else {
final String toDownloadMessageId = findNextMessageToDownload(db, now, subId);
if (toDownloadMessageId != null) {
return true;
}
} }
} }
// Messages may be in the process of sending/downloading even when there are no pending // Messages may be in the process of sending/downloading even when there are no pending
@@ -232,6 +237,21 @@ public class ProcessPendingMessagesAction extends Action implements Parcelable {
return false; return false;
} }
private static int[] getActiveSubscriptionIds() {
if (!OsUtil.isAtLeastL_MR1()) {
return new int[] { ParticipantData.DEFAULT_SELF_SUB_ID };
}
List<SubscriptionInfo> subscriptions = PhoneUtils.getDefault().toLMr1()
.getActiveSubscriptionInfoList();
int numSubs = subscriptions.size();
int[] result = new int[numSubs];
for (int i = 0; i < numSubs; i++) {
result[i] = subscriptions.get(i).getSubscriptionId();
}
return result;
}
/** /**
* Queue any pending actions * Queue any pending actions
* @param actionState * @param actionState
@@ -240,37 +260,44 @@ public class ProcessPendingMessagesAction extends Action implements Parcelable {
private boolean queueActions(final Action processingAction) { private boolean queueActions(final Action processingAction) {
final DatabaseWrapper db = DataModel.get().getDatabase(); final DatabaseWrapper db = DataModel.get().getDatabase();
final long now = System.currentTimeMillis(); final long now = System.currentTimeMillis();
boolean succeeded = true; boolean succeeded = false;
// Will queue no more than one message to send plus one message to download // Will queue no more than one message per subscription to send plus one message to download
// This keeps outgoing messages "in order" but allow downloads to happen even if sending // This keeps outgoing messages "in order" but allow downloads to happen even if sending
// gets blocked until messages time out. Manual resend bumps messages to head of queue. // gets blocked until messages time out. Manual resend bumps messages to head of queue.
final String toSendMessageId = findNextMessageToSend(db, now); for (int subId : getActiveSubscriptionIds()) {
final String toDownloadMessageId = findNextMessageToDownload(db, now); final String toSendMessageId = findNextMessageToSend(db, now, subId);
if (toSendMessageId != null) { final String toDownloadMessageId = findNextMessageToDownload(db, now, subId);
LogUtil.i(TAG, "ProcessPendingMessagesAction: Queueing message " + toSendMessageId if (toSendMessageId != null) {
+ " for sending"); LogUtil.i(TAG, "ProcessPendingMessagesAction: Queueing message " + toSendMessageId
// This could queue nothing + " for sending");
if (!SendMessageAction.queueForSendInBackground(toSendMessageId, processingAction)) { // This could queue nothing
LogUtil.w(TAG, "ProcessPendingMessagesAction: Failed to queue message " if (!SendMessageAction.queueForSendInBackground(toSendMessageId,
+ toSendMessageId + " for sending"); processingAction)) {
succeeded = false; LogUtil.w(TAG, "ProcessPendingMessagesAction: Failed to queue message "
+ toSendMessageId + " for sending");
} else {
succeeded = true;
}
} }
} if (toDownloadMessageId != null) {
if (toDownloadMessageId != null) { LogUtil.i(TAG, "ProcessPendingMessagesAction: Queueing message "
LogUtil.i(TAG, "ProcessPendingMessagesAction: Queueing message " + toDownloadMessageId
+ " for download");
// This could queue nothing
if (!DownloadMmsAction.queueMmsForDownloadInBackground(toDownloadMessageId,
processingAction)) {
LogUtil.w(TAG, "ProcessPendingMessagesAction: Failed to queue message "
+ toDownloadMessageId + " for download"); + toDownloadMessageId + " for download");
succeeded = false; // This could queue nothing
if (!DownloadMmsAction.queueMmsForDownloadInBackground(toDownloadMessageId,
processingAction)) {
LogUtil.w(TAG, "ProcessPendingMessagesAction: Failed to queue message "
+ toDownloadMessageId + " for download");
} else {
succeeded = true;
}
} }
} if (toSendMessageId == null && toDownloadMessageId == null) {
if (toSendMessageId == null && toDownloadMessageId == null) { if (LogUtil.isLoggable(TAG, LogUtil.DEBUG)) {
if (LogUtil.isLoggable(TAG, LogUtil.DEBUG)) { LogUtil.d(TAG, "ProcessPendingMessagesAction: No messages to send or download");
LogUtil.d(TAG, "ProcessPendingMessagesAction: No messages to send or download"); }
succeeded = true;
} }
} }
return succeeded; return succeeded;
@@ -293,7 +320,21 @@ public class ProcessPendingMessagesAction extends Action implements Parcelable {
return null; return null;
} }
private static String findNextMessageToSend(final DatabaseWrapper db, final long now) { private static String prefixColumnWithTable(final String tableName, final String column) {
return tableName + "." + column;
}
private static String[] prefixProjectionWithTable(final String tableName,
final String[] projection) {
String[] result = new String[projection.length];
for (int i = 0; i < projection.length; i++) {
result[i] = prefixColumnWithTable(tableName, projection[i]);
}
return result;
}
private static String findNextMessageToSend(final DatabaseWrapper db, final long now,
final int subId) {
String toSendMessageId = null; String toSendMessageId = null;
db.beginTransaction(); db.beginTransaction();
Cursor sending = null; Cursor sending = null;
@@ -302,12 +343,25 @@ public class ProcessPendingMessagesAction extends Action implements Parcelable {
int pendingCnt = 0; int pendingCnt = 0;
int failedCnt = 0; int failedCnt = 0;
try { try {
String[] projection = prefixProjectionWithTable(DatabaseHelper.MESSAGES_TABLE,
MessageData.getProjection());
String subIdClause =
prefixColumnWithTable(DatabaseHelper.MESSAGES_TABLE,
MessageColumns.SELF_PARTICIPANT_ID)
+ " = "
+ prefixColumnWithTable(DatabaseHelper.PARTICIPANTS_TABLE,
ParticipantColumns._ID)
+ " AND " + ParticipantColumns.SUB_ID + " =?";
// First check to see if we have any messages already sending // First check to see if we have any messages already sending
sending = db.query(DatabaseHelper.MESSAGES_TABLE, sending = db.query(DatabaseHelper.MESSAGES_TABLE + ","
MessageData.getProjection(), + DatabaseHelper.PARTICIPANTS_TABLE,
DatabaseHelper.MessageColumns.STATUS + " IN (?, ?)", projection,
DatabaseHelper.MessageColumns.STATUS + " IN (?, ?)"
+ " AND " + subIdClause,
new String[]{Integer.toString(MessageData.BUGLE_STATUS_OUTGOING_SENDING), new String[]{Integer.toString(MessageData.BUGLE_STATUS_OUTGOING_SENDING),
Integer.toString(MessageData.BUGLE_STATUS_OUTGOING_RESENDING)}, Integer.toString(MessageData.BUGLE_STATUS_OUTGOING_RESENDING),
Integer.toString(subId)},
null, null,
null, null,
DatabaseHelper.MessageColumns.RECEIVED_TIMESTAMP + " ASC"); DatabaseHelper.MessageColumns.RECEIVED_TIMESTAMP + " ASC");
@@ -317,12 +371,14 @@ public class ProcessPendingMessagesAction extends Action implements Parcelable {
final ContentValues values = new ContentValues(); final ContentValues values = new ContentValues();
values.put(DatabaseHelper.MessageColumns.STATUS, values.put(DatabaseHelper.MessageColumns.STATUS,
MessageData.BUGLE_STATUS_OUTGOING_FAILED); MessageData.BUGLE_STATUS_OUTGOING_FAILED);
cursor = db.query(DatabaseHelper.MESSAGES_TABLE, cursor = db.query(DatabaseHelper.MESSAGES_TABLE + ","
MessageData.getProjection(), + DatabaseHelper.PARTICIPANTS_TABLE,
projection,
DatabaseHelper.MessageColumns.STATUS + " IN (" DatabaseHelper.MessageColumns.STATUS + " IN ("
+ MessageData.BUGLE_STATUS_OUTGOING_YET_TO_SEND + "," + MessageData.BUGLE_STATUS_OUTGOING_YET_TO_SEND + ","
+ MessageData.BUGLE_STATUS_OUTGOING_AWAITING_RETRY + ")", + MessageData.BUGLE_STATUS_OUTGOING_AWAITING_RETRY + ")"
null, + " AND " + subIdClause,
new String[]{Integer.toString(subId)},
null, null,
null, null,
DatabaseHelper.MessageColumns.RECEIVED_TIMESTAMP + " ASC"); DatabaseHelper.MessageColumns.RECEIVED_TIMESTAMP + " ASC");
@@ -388,31 +444,49 @@ public class ProcessPendingMessagesAction extends Action implements Parcelable {
return toSendMessageId; return toSendMessageId;
} }
private static String findNextMessageToDownload(final DatabaseWrapper db, final long now) { private static String findNextMessageToDownload(final DatabaseWrapper db, final long now,
final int subId) {
String toDownloadMessageId = null; String toDownloadMessageId = null;
db.beginTransaction(); db.beginTransaction();
Cursor cursor = null; Cursor cursor = null;
int downloadingCnt = 0; int downloadingCnt = 0;
int pendingCnt = 0; int pendingCnt = 0;
try { try {
String[] projection = prefixProjectionWithTable(DatabaseHelper.MESSAGES_TABLE,
MessageData.getProjection());
String subIdClause =
prefixColumnWithTable(DatabaseHelper.MESSAGES_TABLE,
MessageColumns.SELF_PARTICIPANT_ID)
+ " = "
+ prefixColumnWithTable(DatabaseHelper.PARTICIPANTS_TABLE,
ParticipantColumns._ID)
+ " AND " + ParticipantColumns.SUB_ID + " =?";
// First check if we have any messages already downloading // First check if we have any messages already downloading
downloadingCnt = (int) db.queryNumEntries(DatabaseHelper.MESSAGES_TABLE, downloadingCnt = (int) db.queryNumEntries(DatabaseHelper.MESSAGES_TABLE
DatabaseHelper.MessageColumns.STATUS + " IN (?, ?)", + "," + DatabaseHelper.PARTICIPANTS_TABLE,
DatabaseHelper.MessageColumns.STATUS + " IN (?, ?)"
+ " AND " + subIdClause,
new String[] { new String[] {
Integer.toString(MessageData.BUGLE_STATUS_INCOMING_AUTO_DOWNLOADING), Integer.toString(MessageData.BUGLE_STATUS_INCOMING_AUTO_DOWNLOADING),
Integer.toString(MessageData.BUGLE_STATUS_INCOMING_MANUAL_DOWNLOADING) Integer.toString(MessageData.BUGLE_STATUS_INCOMING_MANUAL_DOWNLOADING),
Integer.toString(subId)
}); });
// TODO: This query is not actually needed if downloadingCnt == 0. // TODO: This query is not actually needed if downloadingCnt == 0.
cursor = db.query(DatabaseHelper.MESSAGES_TABLE, cursor = db.query(DatabaseHelper.MESSAGES_TABLE + ","
MessageData.getProjection(), + DatabaseHelper.PARTICIPANTS_TABLE,
projection,
DatabaseHelper.MessageColumns.STATUS + " =? OR " DatabaseHelper.MessageColumns.STATUS + " =? OR "
+ DatabaseHelper.MessageColumns.STATUS + " =?", + DatabaseHelper.MessageColumns.STATUS + " =?"
+ " AND " + subIdClause,
new String[]{ new String[]{
Integer.toString( Integer.toString(
MessageData.BUGLE_STATUS_INCOMING_RETRYING_AUTO_DOWNLOAD), MessageData.BUGLE_STATUS_INCOMING_RETRYING_AUTO_DOWNLOAD),
Integer.toString( Integer.toString(
MessageData.BUGLE_STATUS_INCOMING_RETRYING_MANUAL_DOWNLOAD) MessageData.BUGLE_STATUS_INCOMING_RETRYING_MANUAL_DOWNLOAD),
Integer.toString(
subId)
}, },
null, null,
null, null,