mirror of
https://github.com/oxen-io/session-android.git
synced 2025-02-17 12:28:24 +00:00
Cache delivery receipts when they arrive before sync message
// FREEBIE
This commit is contained in:
parent
4696837f2f
commit
49f60971bd
@ -0,0 +1,56 @@
|
|||||||
|
package org.thoughtcrime.securesms.database;
|
||||||
|
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import org.thoughtcrime.securesms.util.LRUCache;
|
||||||
|
|
||||||
|
public class EarlyReceiptCache {
|
||||||
|
|
||||||
|
private static final String TAG = EarlyReceiptCache.class.getSimpleName();
|
||||||
|
|
||||||
|
private final LRUCache<Placeholder, Long> cache = new LRUCache<>(100);
|
||||||
|
|
||||||
|
public synchronized void increment(long timestamp, String address) {
|
||||||
|
Log.w(TAG, this+"");
|
||||||
|
Log.w(TAG, String.format("Early receipt: %d,%s", timestamp, address));
|
||||||
|
Placeholder tuple = new Placeholder(timestamp, address);
|
||||||
|
Long count = cache.get(tuple);
|
||||||
|
|
||||||
|
if (count != null) {
|
||||||
|
cache.put(tuple, ++count);
|
||||||
|
} else {
|
||||||
|
cache.put(tuple, 1L);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized long remove(long timestamp, String address) {
|
||||||
|
Long count = cache.remove(new Placeholder(timestamp, address));
|
||||||
|
Log.w(TAG, this+"");
|
||||||
|
Log.w(TAG, String.format("Checking early receipts (%d, %s): %d", timestamp, address, count));
|
||||||
|
return count != null ? count : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Placeholder {
|
||||||
|
|
||||||
|
private final long timestamp;
|
||||||
|
private final @NonNull String address;
|
||||||
|
|
||||||
|
private Placeholder(long timestamp, @NonNull String address) {
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
return other != null && other instanceof Placeholder &&
|
||||||
|
((Placeholder)other).timestamp == this.timestamp &&
|
||||||
|
((Placeholder)other).address.equals(this.address);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return (int)timestamp ^ address.hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -144,6 +144,7 @@ public class MmsDatabase extends MessagingDatabase {
|
|||||||
|
|
||||||
private static final String RAW_ID_WHERE = TABLE_NAME + "._id = ?";
|
private static final String RAW_ID_WHERE = TABLE_NAME + "._id = ?";
|
||||||
|
|
||||||
|
private final EarlyReceiptCache earlyReceiptCache = new EarlyReceiptCache();
|
||||||
private final JobManager jobManager;
|
private final JobManager jobManager;
|
||||||
|
|
||||||
public MmsDatabase(Context context, SQLiteOpenHelper databaseHelper) {
|
public MmsDatabase(Context context, SQLiteOpenHelper databaseHelper) {
|
||||||
@ -193,6 +194,7 @@ public class MmsDatabase extends MessagingDatabase {
|
|||||||
MmsAddressDatabase addressDatabase = DatabaseFactory.getMmsAddressDatabase(context);
|
MmsAddressDatabase addressDatabase = DatabaseFactory.getMmsAddressDatabase(context);
|
||||||
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
||||||
Cursor cursor = null;
|
Cursor cursor = null;
|
||||||
|
boolean found = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cursor = database.query(TABLE_NAME, new String[] {ID, THREAD_ID, MESSAGE_BOX}, DATE_SENT + " = ?", new String[] {String.valueOf(timestamp)}, null, null, null, null);
|
cursor = database.query(TABLE_NAME, new String[] {ID, THREAD_ID, MESSAGE_BOX}, DATE_SENT + " = ?", new String[] {String.valueOf(timestamp)}, null, null, null, null);
|
||||||
@ -210,6 +212,8 @@ public class MmsDatabase extends MessagingDatabase {
|
|||||||
long id = cursor.getLong(cursor.getColumnIndexOrThrow(ID));
|
long id = cursor.getLong(cursor.getColumnIndexOrThrow(ID));
|
||||||
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_ID));
|
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_ID));
|
||||||
|
|
||||||
|
found = true;
|
||||||
|
|
||||||
database.execSQL("UPDATE " + TABLE_NAME + " SET " +
|
database.execSQL("UPDATE " + TABLE_NAME + " SET " +
|
||||||
RECEIPT_COUNT + " = " + RECEIPT_COUNT + " + 1 WHERE " + ID + " = ?",
|
RECEIPT_COUNT + " = " + RECEIPT_COUNT + " + 1 WHERE " + ID + " = ?",
|
||||||
new String[] {String.valueOf(id)});
|
new String[] {String.valueOf(id)});
|
||||||
@ -223,6 +227,14 @@ public class MmsDatabase extends MessagingDatabase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
try {
|
||||||
|
earlyReceiptCache.increment(timestamp, canonicalizeNumber(context, address));
|
||||||
|
} catch (InvalidNumberException e) {
|
||||||
|
Log.w(TAG, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (cursor != null)
|
if (cursor != null)
|
||||||
cursor.close();
|
cursor.close();
|
||||||
@ -749,6 +761,16 @@ public class MmsDatabase extends MessagingDatabase {
|
|||||||
contentValues.put(THREAD_ID, threadId);
|
contentValues.put(THREAD_ID, threadId);
|
||||||
contentValues.put(READ, 1);
|
contentValues.put(READ, 1);
|
||||||
contentValues.put(DATE_RECEIVED, System.currentTimeMillis());
|
contentValues.put(DATE_RECEIVED, System.currentTimeMillis());
|
||||||
|
|
||||||
|
if (message.getRecipients().isSingleRecipient()) {
|
||||||
|
try {
|
||||||
|
contentValues.put(RECEIPT_COUNT, earlyReceiptCache.remove(message.getSentTimeMillis(),
|
||||||
|
canonicalizeNumber(context, message.getRecipients().getPrimaryRecipient().getNumber())));
|
||||||
|
} catch (InvalidNumberException e) {
|
||||||
|
Log.w(TAG, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
contentValues.remove(ADDRESS);
|
contentValues.remove(ADDRESS);
|
||||||
|
|
||||||
long messageId = insertMediaMessage(masterSecret, addresses, message.getBody(),
|
long messageId = insertMediaMessage(masterSecret, addresses, message.getBody(),
|
||||||
|
@ -41,6 +41,7 @@ import org.thoughtcrime.securesms.sms.IncomingGroupMessage;
|
|||||||
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
|
import org.thoughtcrime.securesms.sms.IncomingTextMessage;
|
||||||
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
import org.thoughtcrime.securesms.sms.OutgoingTextMessage;
|
||||||
import org.thoughtcrime.securesms.util.JsonUtils;
|
import org.thoughtcrime.securesms.util.JsonUtils;
|
||||||
|
import org.thoughtcrime.securesms.util.LRUCache;
|
||||||
import org.whispersystems.jobqueue.JobManager;
|
import org.whispersystems.jobqueue.JobManager;
|
||||||
import org.whispersystems.textsecure.api.util.InvalidNumberException;
|
import org.whispersystems.textsecure.api.util.InvalidNumberException;
|
||||||
|
|
||||||
@ -97,6 +98,7 @@ public class SmsDatabase extends MessagingDatabase {
|
|||||||
MISMATCHED_IDENTITIES
|
MISMATCHED_IDENTITIES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private static final EarlyReceiptCache earlyReceiptCache = new EarlyReceiptCache();
|
||||||
private final JobManager jobManager;
|
private final JobManager jobManager;
|
||||||
|
|
||||||
public SmsDatabase(Context context, SQLiteOpenHelper databaseHelper) {
|
public SmsDatabase(Context context, SQLiteOpenHelper databaseHelper) {
|
||||||
@ -252,8 +254,9 @@ public class SmsDatabase extends MessagingDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void incrementDeliveryReceiptCount(String address, long timestamp) {
|
public void incrementDeliveryReceiptCount(String address, long timestamp) {
|
||||||
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
||||||
Cursor cursor = null;
|
Cursor cursor = null;
|
||||||
|
boolean foundMessage = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
cursor = database.query(TABLE_NAME, new String[] {ID, THREAD_ID, ADDRESS, TYPE},
|
cursor = database.query(TABLE_NAME, new String[] {ID, THREAD_ID, ADDRESS, TYPE},
|
||||||
@ -276,12 +279,22 @@ public class SmsDatabase extends MessagingDatabase {
|
|||||||
|
|
||||||
DatabaseFactory.getThreadDatabase(context).update(threadId, false);
|
DatabaseFactory.getThreadDatabase(context).update(threadId, false);
|
||||||
notifyConversationListeners(threadId);
|
notifyConversationListeners(threadId);
|
||||||
|
foundMessage = true;
|
||||||
}
|
}
|
||||||
} catch (InvalidNumberException e) {
|
} catch (InvalidNumberException e) {
|
||||||
Log.w("SmsDatabase", e);
|
Log.w(TAG, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!foundMessage) {
|
||||||
|
try {
|
||||||
|
earlyReceiptCache.increment(timestamp, canonicalizeNumber(context, address));
|
||||||
|
} catch (InvalidNumberException e) {
|
||||||
|
Log.w(TAG, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} finally {
|
} finally {
|
||||||
if (cursor != null)
|
if (cursor != null)
|
||||||
cursor.close();
|
cursor.close();
|
||||||
@ -474,8 +487,10 @@ public class SmsDatabase extends MessagingDatabase {
|
|||||||
else if (message.isEndSession()) type |= Types.END_SESSION_BIT;
|
else if (message.isEndSession()) type |= Types.END_SESSION_BIT;
|
||||||
if (forceSms) type |= Types.MESSAGE_FORCE_SMS_BIT;
|
if (forceSms) type |= Types.MESSAGE_FORCE_SMS_BIT;
|
||||||
|
|
||||||
|
String address = message.getRecipients().getPrimaryRecipient().getNumber();
|
||||||
|
|
||||||
ContentValues contentValues = new ContentValues(6);
|
ContentValues contentValues = new ContentValues(6);
|
||||||
contentValues.put(ADDRESS, PhoneNumberUtils.formatNumber(message.getRecipients().getPrimaryRecipient().getNumber()));
|
contentValues.put(ADDRESS, PhoneNumberUtils.formatNumber(address));
|
||||||
contentValues.put(THREAD_ID, threadId);
|
contentValues.put(THREAD_ID, threadId);
|
||||||
contentValues.put(BODY, message.getMessageBody());
|
contentValues.put(BODY, message.getMessageBody());
|
||||||
contentValues.put(DATE_RECEIVED, System.currentTimeMillis());
|
contentValues.put(DATE_RECEIVED, System.currentTimeMillis());
|
||||||
@ -483,6 +498,12 @@ public class SmsDatabase extends MessagingDatabase {
|
|||||||
contentValues.put(READ, 1);
|
contentValues.put(READ, 1);
|
||||||
contentValues.put(TYPE, type);
|
contentValues.put(TYPE, type);
|
||||||
|
|
||||||
|
try {
|
||||||
|
contentValues.put(RECEIPT_COUNT, earlyReceiptCache.remove(date, canonicalizeNumber(context, address)));
|
||||||
|
} catch (InvalidNumberException e) {
|
||||||
|
Log.w(TAG, e);
|
||||||
|
}
|
||||||
|
|
||||||
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
SQLiteDatabase db = databaseHelper.getWritableDatabase();
|
||||||
long messageId = db.insert(TABLE_NAME, ADDRESS, contentValues);
|
long messageId = db.insert(TABLE_NAME, ADDRESS, contentValues);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user