This commit is contained in:
Moxie Marlinspike
2018-02-07 14:01:37 -08:00
parent 8bec5a96f5
commit d567534609
72 changed files with 1164 additions and 505 deletions

View File

@@ -33,6 +33,8 @@ import android.util.Pair;
import net.sqlcipher.database.SQLiteDatabase;
import org.json.JSONArray;
import org.json.JSONException;
import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.attachments.AttachmentId;
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
@@ -44,6 +46,7 @@ import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
import org.thoughtcrime.securesms.mms.MediaStream;
import org.thoughtcrime.securesms.mms.MmsException;
import org.thoughtcrime.securesms.mms.PartAuthority;
import org.thoughtcrime.securesms.util.JsonUtils;
import org.thoughtcrime.securesms.util.MediaUtil;
import org.thoughtcrime.securesms.util.MediaUtil.ThumbnailData;
import org.thoughtcrime.securesms.util.StorageUtil;
@@ -55,6 +58,7 @@ import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;
@@ -67,7 +71,7 @@ public class AttachmentDatabase extends Database {
public static final String TABLE_NAME = "part";
public static final String ROW_ID = "_id";
public static final String ATTACHMENT_ID_ALIAS = "attachment_id";
static final String ATTACHMENT_JSON_ALIAS = "attachment_json";
static final String MMS_ID = "mid";
static final String CONTENT_TYPE = "ct";
static final String NAME = "name";
@@ -82,7 +86,8 @@ public class AttachmentDatabase extends Database {
public static final String UNIQUE_ID = "unique_id";
static final String DIGEST = "digest";
static final String VOICE_NOTE = "voice_note";
public static final String FAST_PREFLIGHT_ID = "fast_preflight_id";
static final String QUOTE = "quote";
static final String FAST_PREFLIGHT_ID = "fast_preflight_id";
public static final String DATA_RANDOM = "data_random";
private static final String THUMBNAIL_RANDOM = "thumbnail_random";
static final String WIDTH = "width";
@@ -97,12 +102,12 @@ public class AttachmentDatabase extends Database {
private static final String PART_ID_WHERE = ROW_ID + " = ? AND " + UNIQUE_ID + " = ?";
private static final String[] PROJECTION = new String[] {ROW_ID + " AS " + ATTACHMENT_ID_ALIAS,
private static final String[] PROJECTION = new String[] {ROW_ID,
MMS_ID, CONTENT_TYPE, NAME, CONTENT_DISPOSITION,
CONTENT_LOCATION, DATA, THUMBNAIL, TRANSFER_STATE,
SIZE, FILE_NAME, THUMBNAIL, THUMBNAIL_ASPECT_RATIO,
UNIQUE_ID, DIGEST, FAST_PREFLIGHT_ID, VOICE_NOTE,
DATA_RANDOM, THUMBNAIL_RANDOM, WIDTH, HEIGHT};
QUOTE, DATA_RANDOM, THUMBNAIL_RANDOM, WIDTH, HEIGHT};
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ROW_ID + " INTEGER PRIMARY KEY, " +
MMS_ID + " INTEGER, " + "seq" + " INTEGER DEFAULT 0, " +
@@ -114,7 +119,7 @@ public class AttachmentDatabase extends Database {
FILE_NAME + " TEXT, " + THUMBNAIL + " TEXT, " + THUMBNAIL_ASPECT_RATIO + " REAL, " +
UNIQUE_ID + " INTEGER NOT NULL, " + DIGEST + " BLOB, " + FAST_PREFLIGHT_ID + " TEXT, " +
VOICE_NOTE + " INTEGER DEFAULT 0, " + DATA_RANDOM + " BLOB, " + THUMBNAIL_RANDOM + " BLOB, " +
WIDTH + " INTEGER DEFAULT 0, " + HEIGHT + " INTEGER DEFAULT 0);";
QUOTE + " INTEGER DEFAULT 0, " + WIDTH + " INTEGER DEFAULT 0, " + HEIGHT + " INTEGER DEFAULT 0);";
public static final String[] CREATE_INDEXS = {
"CREATE INDEX IF NOT EXISTS part_mms_id_index ON " + TABLE_NAME + " (" + MMS_ID + ");",
@@ -181,9 +186,15 @@ public class AttachmentDatabase extends Database {
try {
cursor = database.query(TABLE_NAME, PROJECTION, PART_ID_WHERE, attachmentId.toStrings(), null, null, null);
if (cursor != null && cursor.moveToFirst()) return getAttachment(cursor);
else return null;
if (cursor != null && cursor.moveToFirst()) {
List<DatabaseAttachment> list = getAttachment(cursor);
if (list != null && list.size() > 0) {
return list.get(0);
}
}
return null;
} finally {
if (cursor != null)
cursor.close();
@@ -200,7 +211,7 @@ public class AttachmentDatabase extends Database {
null, null, null);
while (cursor != null && cursor.moveToNext()) {
results.add(getAttachment(cursor));
results.addAll(getAttachment(cursor));
}
return results;
@@ -218,7 +229,7 @@ public class AttachmentDatabase extends Database {
try {
cursor = database.query(TABLE_NAME, PROJECTION, TRANSFER_STATE + " = ?", new String[] {String.valueOf(TRANSFER_PROGRESS_STARTED)}, null, null, null);
while (cursor != null && cursor.moveToNext()) {
attachments.add(getAttachment(cursor));
attachments.addAll(getAttachment(cursor));
}
} finally {
if (cursor != null) cursor.close();
@@ -327,15 +338,19 @@ public class AttachmentDatabase extends Database {
thumbnailExecutor.submit(new ThumbnailFetchCallable(attachmentId));
}
void insertAttachmentsForMessage(long mmsId, @NonNull List<Attachment> attachments)
void insertAttachmentsForMessage(long mmsId, @NonNull List<Attachment> attachments, @NonNull List<Attachment> quoteAttachment)
throws MmsException
{
Log.w(TAG, "insertParts(" + attachments.size() + ")");
for (Attachment attachment : attachments) {
AttachmentId attachmentId = insertAttachment(mmsId, attachment);
AttachmentId attachmentId = insertAttachment(mmsId, attachment, attachment.isQuote());
Log.w(TAG, "Inserted attachment at ID: " + attachmentId);
}
for (Attachment attachment : quoteAttachment) {
insertAttachment(mmsId, attachment, true);
}
}
public @NonNull Attachment updateAttachmentData(@NonNull Attachment attachment,
@@ -376,7 +391,8 @@ public class AttachmentDatabase extends Database {
databaseAttachment.getFastPreflightId(),
databaseAttachment.isVoiceNote(),
mediaStream.getWidth(),
mediaStream.getHeight());
mediaStream.getHeight(),
databaseAttachment.isQuote());
}
@@ -519,28 +535,68 @@ public class AttachmentDatabase extends Database {
}
}
DatabaseAttachment getAttachment(@NonNull Cursor cursor) {
return new DatabaseAttachment(new AttachmentId(cursor.getLong(cursor.getColumnIndexOrThrow(ATTACHMENT_ID_ALIAS)),
cursor.getLong(cursor.getColumnIndexOrThrow(UNIQUE_ID))),
cursor.getLong(cursor.getColumnIndexOrThrow(MMS_ID)),
!cursor.isNull(cursor.getColumnIndexOrThrow(DATA)),
!cursor.isNull(cursor.getColumnIndexOrThrow(THUMBNAIL)),
cursor.getString(cursor.getColumnIndexOrThrow(CONTENT_TYPE)),
cursor.getInt(cursor.getColumnIndexOrThrow(TRANSFER_STATE)),
cursor.getLong(cursor.getColumnIndexOrThrow(SIZE)),
StorageUtil.getCleanFileName(cursor.getString(cursor.getColumnIndexOrThrow(FILE_NAME))),
cursor.getString(cursor.getColumnIndexOrThrow(CONTENT_LOCATION)),
cursor.getString(cursor.getColumnIndexOrThrow(CONTENT_DISPOSITION)),
cursor.getString(cursor.getColumnIndexOrThrow(NAME)),
cursor.getBlob(cursor.getColumnIndexOrThrow(DIGEST)),
cursor.getString(cursor.getColumnIndexOrThrow(FAST_PREFLIGHT_ID)),
cursor.getInt(cursor.getColumnIndexOrThrow(VOICE_NOTE)) == 1,
cursor.getInt(cursor.getColumnIndexOrThrow(WIDTH)),
cursor.getInt(cursor.getColumnIndexOrThrow(HEIGHT)));
public List<DatabaseAttachment> getAttachment(@NonNull Cursor cursor) {
try {
if (cursor.getColumnIndex(AttachmentDatabase.ATTACHMENT_JSON_ALIAS) != -1) {
if (cursor.isNull(cursor.getColumnIndexOrThrow(ATTACHMENT_JSON_ALIAS))) {
return new LinkedList<>();
}
List<DatabaseAttachment> result = new LinkedList<>();
JSONArray array = new JSONArray(cursor.getString(cursor.getColumnIndexOrThrow(ATTACHMENT_JSON_ALIAS)));
for (int i=0;i<array.length();i++) {
JsonUtils.SaneJSONObject object = new JsonUtils.SaneJSONObject(array.getJSONObject(i));
if (!object.isNull(ROW_ID)) {
result.add(new DatabaseAttachment(new AttachmentId(object.getLong(ROW_ID), object.getLong(UNIQUE_ID)),
object.getLong(MMS_ID),
!TextUtils.isEmpty(object.getString(DATA)),
!TextUtils.isEmpty(object.getString(THUMBNAIL)),
object.getString(CONTENT_TYPE),
object.getInt(TRANSFER_STATE),
object.getLong(SIZE),
object.getString(FILE_NAME),
object.getString(CONTENT_LOCATION),
object.getString(CONTENT_DISPOSITION),
object.getString(NAME),
null,
object.getString(FAST_PREFLIGHT_ID),
object.getInt(VOICE_NOTE) == 1,
object.getInt(WIDTH),
object.getInt(HEIGHT),
object.getInt(QUOTE) == 1));
}
}
return result;
} else {
return Collections.singletonList(new DatabaseAttachment(new AttachmentId(cursor.getLong(cursor.getColumnIndexOrThrow(ROW_ID)),
cursor.getLong(cursor.getColumnIndexOrThrow(UNIQUE_ID))),
cursor.getLong(cursor.getColumnIndexOrThrow(MMS_ID)),
!cursor.isNull(cursor.getColumnIndexOrThrow(DATA)),
!cursor.isNull(cursor.getColumnIndexOrThrow(THUMBNAIL)),
cursor.getString(cursor.getColumnIndexOrThrow(CONTENT_TYPE)),
cursor.getInt(cursor.getColumnIndexOrThrow(TRANSFER_STATE)),
cursor.getLong(cursor.getColumnIndexOrThrow(SIZE)),
cursor.getString(cursor.getColumnIndexOrThrow(FILE_NAME)),
cursor.getString(cursor.getColumnIndexOrThrow(CONTENT_LOCATION)),
cursor.getString(cursor.getColumnIndexOrThrow(CONTENT_DISPOSITION)),
cursor.getString(cursor.getColumnIndexOrThrow(NAME)),
cursor.getBlob(cursor.getColumnIndexOrThrow(DIGEST)),
cursor.getString(cursor.getColumnIndexOrThrow(FAST_PREFLIGHT_ID)),
cursor.getInt(cursor.getColumnIndexOrThrow(VOICE_NOTE)) == 1,
cursor.getInt(cursor.getColumnIndexOrThrow(WIDTH)),
cursor.getInt(cursor.getColumnIndexOrThrow(HEIGHT)),
cursor.getInt(cursor.getColumnIndexOrThrow(QUOTE)) == 1));
}
} catch (JSONException e) {
throw new AssertionError(e);
}
}
private AttachmentId insertAttachment(long mmsId, Attachment attachment)
private AttachmentId insertAttachment(long mmsId, Attachment attachment, boolean quote)
throws MmsException
{
Log.w(TAG, "Inserting attachment for mms id: " + mmsId);
@@ -569,6 +625,7 @@ public class AttachmentDatabase extends Database {
contentValues.put(VOICE_NOTE, attachment.isVoiceNote() ? 1 : 0);
contentValues.put(WIDTH, attachment.getWidth());
contentValues.put(HEIGHT, attachment.getHeight());
contentValues.put(QUOTE, quote);
if (dataInfo != null) {
contentValues.put(DATA, dataInfo.file.getAbsolutePath());

View File

@@ -13,9 +13,11 @@ import org.thoughtcrime.securesms.attachments.Attachment;
import org.thoughtcrime.securesms.attachments.DatabaseAttachment;
import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
import java.util.List;
public class MediaDatabase extends Database {
private static final String BASE_MEDIA_QUERY = "SELECT " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.ROW_ID + " AS " + AttachmentDatabase.ATTACHMENT_ID_ALIAS + ", "
private static final String BASE_MEDIA_QUERY = "SELECT " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.ROW_ID + " AS " + AttachmentDatabase.ROW_ID + ", "
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.CONTENT_TYPE + ", "
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.THUMBNAIL_ASPECT_RATIO + ", "
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.UNIQUE_ID + ", "
@@ -32,6 +34,7 @@ public class MediaDatabase extends Database {
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.VOICE_NOTE + ", "
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.WIDTH + ", "
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.HEIGHT + ", "
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.QUOTE + ", "
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.NAME + ", "
+ MmsDatabase.TABLE_NAME + "." + MmsDatabase.MESSAGE_BOX + ", "
+ MmsDatabase.TABLE_NAME + "." + MmsDatabase.DATE_SENT + ", "
@@ -48,7 +51,7 @@ public class MediaDatabase extends Database {
private static final String GALLERY_MEDIA_QUERY = String.format(BASE_MEDIA_QUERY, AttachmentDatabase.CONTENT_TYPE + " LIKE 'image/%' OR " + AttachmentDatabase.CONTENT_TYPE + " LIKE 'video/%'");
private static final String DOCUMENT_MEDIA_QUERY = String.format(BASE_MEDIA_QUERY, AttachmentDatabase.CONTENT_TYPE + " NOT LIKE 'image/%' AND " + AttachmentDatabase.CONTENT_TYPE + " NOT LIKE 'video/%' AND " + AttachmentDatabase.CONTENT_TYPE + " NOT LIKE 'audio/%'");
public MediaDatabase(Context context, SQLCipherOpenHelper databaseHelper) {
MediaDatabase(Context context, SQLCipherOpenHelper databaseHelper) {
super(context, databaseHelper);
}
@@ -89,11 +92,11 @@ public class MediaDatabase extends Database {
}
public static MediaRecord from(@NonNull Context context, @NonNull Cursor cursor) {
AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context);
DatabaseAttachment attachment = attachmentDatabase.getAttachment(cursor);
String serializedAddress = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.ADDRESS));
boolean outgoing = MessagingDatabase.Types.isOutgoingMessageType(cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.MESSAGE_BOX)));
Address address = null;
AttachmentDatabase attachmentDatabase = DatabaseFactory.getAttachmentDatabase(context);
List<DatabaseAttachment> attachments = attachmentDatabase.getAttachment(cursor);
String serializedAddress = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.ADDRESS));
boolean outgoing = MessagingDatabase.Types.isOutgoingMessageType(cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.MESSAGE_BOX)));
Address address = null;
if (serializedAddress != null) {
address = Address.fromSerialized(serializedAddress);
@@ -107,7 +110,7 @@ public class MediaDatabase extends Database {
date = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.DATE_RECEIVED));
}
return new MediaRecord(attachment, address, date, outgoing);
return new MediaRecord(attachments != null && attachments.size() > 0 ? attachments.get(0) : null, address, date, outgoing);
}
public DatabaseAttachment getAttachment() {

View File

@@ -44,6 +44,7 @@ import org.thoughtcrime.securesms.database.helpers.SQLCipherOpenHelper;
import org.thoughtcrime.securesms.database.model.MediaMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.MessageRecord;
import org.thoughtcrime.securesms.database.model.NotificationMmsMessageRecord;
import org.thoughtcrime.securesms.database.model.Quote;
import org.thoughtcrime.securesms.jobs.TrimThreadJob;
import org.thoughtcrime.securesms.mms.IncomingMediaMessage;
import org.thoughtcrime.securesms.mms.MmsException;
@@ -51,6 +52,7 @@ import org.thoughtcrime.securesms.mms.OutgoingExpirationUpdateMessage;
import org.thoughtcrime.securesms.mms.OutgoingGroupMediaMessage;
import org.thoughtcrime.securesms.mms.OutgoingMediaMessage;
import org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage;
import org.thoughtcrime.securesms.mms.QuoteModel;
import org.thoughtcrime.securesms.mms.SlideDeck;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientFormattingException;
@@ -86,6 +88,11 @@ public class MmsDatabase extends MessagingDatabase {
static final String PART_COUNT = "part_count";
static final String NETWORK_FAILURE = "network_failures";
static final String QUOTE_ID = "quote_id";
static final String QUOTE_AUTHOR = "quote_author";
static final String QUOTE_BODY = "quote_body";
static final String QUOTE_ATTACHMENT = "quote_attachment";
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ID + " INTEGER PRIMARY KEY, " +
THREAD_ID + " INTEGER, " + DATE_SENT + " INTEGER, " + DATE_RECEIVED + " INTEGER, " + MESSAGE_BOX + " INTEGER, " +
READ + " INTEGER DEFAULT 0, " + "m_id" + " TEXT, " + "sub" + " TEXT, " +
@@ -102,7 +109,8 @@ public class MmsDatabase extends MessagingDatabase {
NETWORK_FAILURE + " TEXT DEFAULT NULL," + "d_rpt" + " INTEGER, " +
SUBSCRIPTION_ID + " INTEGER DEFAULT -1, " + EXPIRES_IN + " INTEGER DEFAULT 0, " +
EXPIRE_STARTED + " INTEGER DEFAULT 0, " + NOTIFIED + " INTEGER DEFAULT 0, " +
READ_RECEIPT_COUNT + " INTEGER DEFAULT 0);";
READ_RECEIPT_COUNT + " INTEGER DEFAULT 0, " + QUOTE_ID + " INTEGER DEFAULT 0, " +
QUOTE_AUTHOR + " TEXT, " + QUOTE_BODY + " TEXT, " + QUOTE_ATTACHMENT + " INTEGER DEFAULT -1);";
public static final String[] CREATE_INDEXS = {
"CREATE INDEX IF NOT EXISTS mms_thread_id_index ON " + TABLE_NAME + " (" + THREAD_ID + ");",
@@ -122,24 +130,26 @@ public class MmsDatabase extends MessagingDatabase {
MESSAGE_SIZE, STATUS, TRANSACTION_ID,
BODY, PART_COUNT, ADDRESS, ADDRESS_DEVICE_ID,
DELIVERY_RECEIPT_COUNT, READ_RECEIPT_COUNT, MISMATCHED_IDENTITIES, NETWORK_FAILURE, SUBSCRIPTION_ID,
EXPIRES_IN, EXPIRE_STARTED, NOTIFIED,
AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.ROW_ID + " AS " + AttachmentDatabase.ATTACHMENT_ID_ALIAS,
AttachmentDatabase.UNIQUE_ID,
AttachmentDatabase.MMS_ID,
AttachmentDatabase.SIZE,
AttachmentDatabase.FILE_NAME,
AttachmentDatabase.DATA,
AttachmentDatabase.THUMBNAIL,
AttachmentDatabase.CONTENT_TYPE,
AttachmentDatabase.CONTENT_LOCATION,
AttachmentDatabase.DIGEST,
AttachmentDatabase.FAST_PREFLIGHT_ID,
AttachmentDatabase.VOICE_NOTE,
AttachmentDatabase.WIDTH,
AttachmentDatabase.HEIGHT,
AttachmentDatabase.CONTENT_DISPOSITION,
AttachmentDatabase.NAME,
AttachmentDatabase.TRANSFER_STATE
EXPIRES_IN, EXPIRE_STARTED, NOTIFIED, QUOTE_ID, QUOTE_AUTHOR, QUOTE_BODY, QUOTE_ATTACHMENT,
"json_group_array(json_object(" +
"'" + AttachmentDatabase.ROW_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.ROW_ID + ", " +
"'" + AttachmentDatabase.UNIQUE_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.UNIQUE_ID + ", " +
"'" + AttachmentDatabase.MMS_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.MMS_ID + ", " +
"'" + AttachmentDatabase.SIZE + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.SIZE + ", " +
"'" + AttachmentDatabase.FILE_NAME + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.FILE_NAME + ", " +
"'" + AttachmentDatabase.DATA + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.DATA + ", " +
"'" + AttachmentDatabase.THUMBNAIL + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.THUMBNAIL + ", " +
"'" + AttachmentDatabase.CONTENT_TYPE + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.CONTENT_TYPE + ", " +
"'" + AttachmentDatabase.CONTENT_LOCATION + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.CONTENT_LOCATION + ", " +
"'" + AttachmentDatabase.FAST_PREFLIGHT_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.FAST_PREFLIGHT_ID + "," +
"'" + AttachmentDatabase.VOICE_NOTE + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.VOICE_NOTE + "," +
"'" + AttachmentDatabase.WIDTH + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.WIDTH + "," +
"'" + AttachmentDatabase.HEIGHT + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.HEIGHT + "," +
"'" + AttachmentDatabase.QUOTE + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.QUOTE + ", " +
"'" + AttachmentDatabase.CONTENT_DISPOSITION + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.CONTENT_DISPOSITION + ", " +
"'" + AttachmentDatabase.NAME + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.NAME + ", " +
"'" + AttachmentDatabase.TRANSFER_STATE + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.TRANSFER_STATE +
")) AS " + AttachmentDatabase.ATTACHMENT_JSON_ALIAS,
};
private static final String RAW_ID_WHERE = TABLE_NAME + "._id = ?";
@@ -276,7 +286,7 @@ public class MmsDatabase extends MessagingDatabase {
return database.rawQuery("SELECT " + Util.join(MMS_PROJECTION, ",") +
" FROM " + MmsDatabase.TABLE_NAME + " LEFT OUTER JOIN " + AttachmentDatabase.TABLE_NAME +
" ON (" + MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID + " = " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.MMS_ID + ")" +
" WHERE " + where, arguments);
" WHERE " + where + " GROUP BY " + MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID, arguments);
}
public Cursor getMessage(long messageId) {
@@ -537,25 +547,37 @@ public class MmsDatabase extends MessagingDatabase {
cursor = rawQuery(RAW_ID_WHERE, new String[] {String.valueOf(messageId)});
if (cursor != null && cursor.moveToNext()) {
List<DatabaseAttachment> associatedAttachments = attachmentDatabase.getAttachmentsForMessage(messageId);
long outboxType = cursor.getLong(cursor.getColumnIndexOrThrow(MESSAGE_BOX));
String body = cursor.getString(cursor.getColumnIndexOrThrow(BODY));
long timestamp = cursor.getLong(cursor.getColumnIndexOrThrow(NORMALIZED_DATE_SENT));
int subscriptionId = cursor.getInt(cursor.getColumnIndexOrThrow(SUBSCRIPTION_ID));
long expiresIn = cursor.getLong(cursor.getColumnIndexOrThrow(EXPIRES_IN));
List<Attachment> attachments = new LinkedList<>(attachmentDatabase.getAttachmentsForMessage(messageId));
String address = cursor.getString(cursor.getColumnIndexOrThrow(ADDRESS));
long threadId = cursor.getLong(cursor.getColumnIndexOrThrow(THREAD_ID));
int distributionType = DatabaseFactory.getThreadDatabase(context).getDistributionType(threadId);
List<Attachment> attachments = Stream.of(associatedAttachments).filterNot(Attachment::isQuote).map(a -> (Attachment)a).toList();
Recipient recipient = Recipient.from(context, Address.fromSerialized(address), false);
long quoteId = cursor.getLong(cursor.getColumnIndexOrThrow(QUOTE_ID));
String quoteAuthor = cursor.getString(cursor.getColumnIndexOrThrow(QUOTE_AUTHOR));
String quoteText = cursor.getString(cursor.getColumnIndexOrThrow(QUOTE_BODY));
List<Attachment> quoteAttachments = Stream.of(associatedAttachments).filter(Attachment::isQuote).map(a -> (Attachment)a).toList();
Recipient recipient = Recipient.from(context, Address.fromSerialized(address), false);
QuoteModel quote = null;
if (quoteId > 0 && (!TextUtils.isEmpty(quoteText) || !quoteAttachments.isEmpty())) {
quote = new QuoteModel(quoteId, Address.fromSerialized(quoteAuthor), quoteText, quoteAttachments);
}
if (body != null && (Types.isGroupQuit(outboxType) || Types.isGroupUpdate(outboxType))) {
return new OutgoingGroupMediaMessage(recipient, body, attachments, timestamp, 0);
return new OutgoingGroupMediaMessage(recipient, body, attachments, timestamp, 0, quote);
} else if (Types.isExpirationTimerUpdate(outboxType)) {
return new OutgoingExpirationUpdateMessage(recipient, timestamp, expiresIn);
}
OutgoingMediaMessage message = new OutgoingMediaMessage(recipient, body, attachments, timestamp, subscriptionId, expiresIn, distributionType);
OutgoingMediaMessage message = new OutgoingMediaMessage(recipient, body, attachments, timestamp, subscriptionId, expiresIn, distributionType, quote);
if (Types.isSecureType(outboxType)) {
return new OutgoingSecureMediaMessage(message);
@@ -604,11 +626,13 @@ public class MmsDatabase extends MessagingDatabase {
databaseAttachment.getFastPreflightId(),
databaseAttachment.isVoiceNote(),
databaseAttachment.getWidth(),
databaseAttachment.getHeight()));
databaseAttachment.getHeight(),
databaseAttachment.isQuote()));
}
return insertMediaMessage(request.getBody(),
attachments,
new LinkedList<>(),
contentValues,
null);
} catch (NoSuchMessageException e) {
@@ -651,12 +675,22 @@ public class MmsDatabase extends MessagingDatabase {
contentValues.put(DATE_SENT, contentValues.getAsLong(DATE_RECEIVED));
}
List<Attachment> quoteAttachments = new LinkedList<>();
if (retrieved.getQuote() != null) {
contentValues.put(QUOTE_ID, retrieved.getQuote().getId());
contentValues.put(QUOTE_BODY, retrieved.getQuote().getText());
contentValues.put(QUOTE_AUTHOR, retrieved.getQuote().getAuthor().serialize());
quoteAttachments = retrieved.getQuote().getAttachments();
}
if (retrieved.isPushMessage() && isDuplicate(retrieved, threadId)) {
Log.w(TAG, "Ignoring duplicate media message (" + retrieved.getSentTimeMillis() + ")");
return Optional.absent();
}
long messageId = insertMediaMessage(retrieved.getBody(), retrieved.getAttachments(), contentValues, null);
long messageId = insertMediaMessage(retrieved.getBody(), retrieved.getAttachments(), quoteAttachments, contentValues, null);
if (!Types.isExpirationTimerUpdate(mailbox)) {
DatabaseFactory.getThreadDatabase(context).incrementUnread(threadId, 1);
@@ -784,7 +818,17 @@ public class MmsDatabase extends MessagingDatabase {
contentValues.put(DELIVERY_RECEIPT_COUNT, Stream.of(earlyDeliveryReceipts.values()).mapToLong(Long::longValue).sum());
contentValues.put(READ_RECEIPT_COUNT, Stream.of(earlyReadReceipts.values()).mapToLong(Long::longValue).sum());
long messageId = insertMediaMessage(message.getBody(), message.getAttachments(), contentValues, insertListener);
List<Attachment> quoteAttachments = new LinkedList<>();
if (message.getOutgoingQuote() != null) {
contentValues.put(QUOTE_ID, message.getOutgoingQuote().getId());
contentValues.put(QUOTE_AUTHOR, message.getOutgoingQuote().getAuthor().serialize());
contentValues.put(QUOTE_BODY, message.getOutgoingQuote().getText());
quoteAttachments.addAll(message.getOutgoingQuote().getAttachments());
}
long messageId = insertMediaMessage(message.getBody(), message.getAttachments(), quoteAttachments, contentValues, insertListener);
if (message.getRecipient().getAddress().isGroup()) {
List<Recipient> members = DatabaseFactory.getGroupDatabase(context).getGroupMembers(message.getRecipient().getAddress().toGroupString(), false);
@@ -806,6 +850,7 @@ public class MmsDatabase extends MessagingDatabase {
private long insertMediaMessage(@Nullable String body,
@NonNull List<Attachment> attachments,
@NonNull List<Attachment> quoteAttachments,
@NonNull ContentValues contentValues,
@Nullable SmsDatabase.InsertListener insertListener)
throws MmsException
@@ -820,7 +865,7 @@ public class MmsDatabase extends MessagingDatabase {
try {
long messageId = db.insert(TABLE_NAME, null, contentValues);
partsDatabase.insertAttachmentsForMessage(messageId, attachments);
partsDatabase.insertAttachmentsForMessage(messageId, attachments, quoteAttachments);
db.setTransactionSuccessful();
return messageId;
@@ -870,7 +915,6 @@ public class MmsDatabase extends MessagingDatabase {
}
}
/*package*/ void deleteThreads(Set<Long> threadIds) {
SQLiteDatabase db = databaseHelper.getWritableDatabase();
String where = "";
@@ -1021,7 +1065,13 @@ public class MmsDatabase extends MessagingDatabase {
new LinkedList<NetworkFailure>(),
message.getSubscriptionId(),
message.getExpiresIn(),
System.currentTimeMillis(), 0);
System.currentTimeMillis(), 0,
message.getOutgoingQuote() != null ?
new Quote(message.getOutgoingQuote().getId(),
message.getOutgoingQuote().getAuthor(),
message.getOutgoingQuote().getText(),
new SlideDeck(context, message.getOutgoingQuote().getAttachments())) :
null);
}
}
@@ -1118,12 +1168,13 @@ public class MmsDatabase extends MessagingDatabase {
List<IdentityKeyMismatch> mismatches = getMismatchedIdentities(mismatchDocument);
List<NetworkFailure> networkFailures = getFailures(networkDocument);
SlideDeck slideDeck = getSlideDeck(cursor);
Quote quote = getQuote(cursor);
return new MediaMmsMessageRecord(context, id, recipient, recipient,
addressDeviceId, dateSent, dateReceived, deliveryReceiptCount,
threadId, body, slideDeck, partCount, box, mismatches,
networkFailures, subscriptionId, expiresIn, expireStarted,
readReceiptCount);
readReceiptCount, quote);
}
private Recipient getRecipientFor(String serialized) {
@@ -1163,8 +1214,24 @@ public class MmsDatabase extends MessagingDatabase {
}
private SlideDeck getSlideDeck(@NonNull Cursor cursor) {
Attachment attachment = DatabaseFactory.getAttachmentDatabase(context).getAttachment(cursor);
return new SlideDeck(context, attachment);
List<DatabaseAttachment> attachment = DatabaseFactory.getAttachmentDatabase(context).getAttachment(cursor);
List<? extends Attachment> messageAttachmnets = Stream.of(attachment).filterNot(Attachment::isQuote).toList();
return new SlideDeck(context, messageAttachmnets);
}
private @Nullable Quote getQuote(@NonNull Cursor cursor) {
long quoteId = cursor.getLong(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_ID));
String quoteAuthor = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_AUTHOR));
String quoteText = cursor.getString(cursor.getColumnIndexOrThrow(MmsDatabase.QUOTE_BODY));
List<DatabaseAttachment> attachments = DatabaseFactory.getAttachmentDatabase(context).getAttachment(cursor);
List<? extends Attachment> quoteAttachments = Stream.of(attachments).filter(Attachment::isQuote).toList();
SlideDeck quoteDeck = new SlideDeck(context, quoteAttachments);
if (quoteId > 0 && !TextUtils.isEmpty(quoteAuthor)) {
return new Quote(quoteId, Address.fromExternal(context, quoteAuthor), quoteText, quoteDeck);
} else {
return null;
}
}
public void close() {

View File

@@ -60,28 +60,20 @@ public class MmsSmsDatabase extends Database {
MmsSmsColumns.EXPIRE_STARTED,
MmsSmsColumns.NOTIFIED,
TRANSPORT,
AttachmentDatabase.ATTACHMENT_ID_ALIAS,
AttachmentDatabase.UNIQUE_ID,
AttachmentDatabase.MMS_ID,
AttachmentDatabase.SIZE,
AttachmentDatabase.FILE_NAME,
AttachmentDatabase.DATA,
AttachmentDatabase.THUMBNAIL,
AttachmentDatabase.CONTENT_TYPE,
AttachmentDatabase.CONTENT_LOCATION,
AttachmentDatabase.DIGEST,
AttachmentDatabase.FAST_PREFLIGHT_ID,
AttachmentDatabase.VOICE_NOTE,
AttachmentDatabase.WIDTH,
AttachmentDatabase.HEIGHT,
AttachmentDatabase.CONTENT_DISPOSITION,
AttachmentDatabase.NAME,
AttachmentDatabase.TRANSFER_STATE};
AttachmentDatabase.ATTACHMENT_JSON_ALIAS,
MmsDatabase.QUOTE_ID,
MmsDatabase.QUOTE_AUTHOR,
MmsDatabase.QUOTE_BODY,
MmsDatabase.QUOTE_ATTACHMENT};
public MmsSmsDatabase(Context context, SQLCipherOpenHelper databaseHelper) {
super(context, databaseHelper);
}
public Cursor getMessagesFor(long timestamp) {
return queryTables(PROJECTION, MmsSmsColumns.NORMALIZED_DATE_SENT + " = " + timestamp, null, null);
}
public Cursor getConversation(long threadId, long limit) {
String order = MmsSmsColumns.NORMALIZED_DATE_RECEIVED + " DESC";
String selection = MmsSmsColumns.THREAD_ID + " = " + threadId;
@@ -155,7 +147,25 @@ public class MmsSmsDatabase extends Database {
"'MMS::' || " + MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID
+ " || '::' || " + MmsDatabase.DATE_SENT
+ " AS " + MmsSmsColumns.UNIQUE_ROW_ID,
AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.ROW_ID + " AS " + AttachmentDatabase.ATTACHMENT_ID_ALIAS,
"json_group_array(json_object(" +
"'" + AttachmentDatabase.ROW_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.ROW_ID + ", " +
"'" + AttachmentDatabase.UNIQUE_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.UNIQUE_ID + ", " +
"'" + AttachmentDatabase.MMS_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.MMS_ID + "," +
"'" + AttachmentDatabase.SIZE + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.SIZE + ", " +
"'" + AttachmentDatabase.FILE_NAME + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.FILE_NAME + ", " +
"'" + AttachmentDatabase.DATA + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.DATA + ", " +
"'" + AttachmentDatabase.THUMBNAIL + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.THUMBNAIL + ", " +
"'" + AttachmentDatabase.CONTENT_TYPE + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.CONTENT_TYPE + ", " +
"'" + AttachmentDatabase.CONTENT_LOCATION + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.CONTENT_LOCATION + ", " +
"'" + AttachmentDatabase.FAST_PREFLIGHT_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.FAST_PREFLIGHT_ID + ", " +
"'" + AttachmentDatabase.VOICE_NOTE + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.VOICE_NOTE + ", " +
"'" + AttachmentDatabase.WIDTH + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.WIDTH + ", " +
"'" + AttachmentDatabase.HEIGHT + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.HEIGHT + ", " +
"'" + AttachmentDatabase.QUOTE + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.QUOTE + ", " +
"'" + AttachmentDatabase.CONTENT_DISPOSITION + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.CONTENT_DISPOSITION + ", " +
"'" + AttachmentDatabase.NAME + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.NAME + ", " +
"'" + AttachmentDatabase.TRANSFER_STATE + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.TRANSFER_STATE +
")) AS " + AttachmentDatabase.ATTACHMENT_JSON_ALIAS,
SmsDatabase.BODY, MmsSmsColumns.READ, MmsSmsColumns.THREAD_ID,
SmsDatabase.TYPE, SmsDatabase.ADDRESS, SmsDatabase.ADDRESS_DEVICE_ID, SmsDatabase.SUBJECT, MmsDatabase.MESSAGE_TYPE,
MmsDatabase.MESSAGE_BOX, SmsDatabase.STATUS, MmsDatabase.PART_COUNT,
@@ -166,22 +176,10 @@ public class MmsSmsDatabase extends Database {
MmsSmsColumns.SUBSCRIPTION_ID, MmsSmsColumns.EXPIRES_IN, MmsSmsColumns.EXPIRE_STARTED,
MmsSmsColumns.NOTIFIED,
MmsDatabase.NETWORK_FAILURE, TRANSPORT,
AttachmentDatabase.UNIQUE_ID,
AttachmentDatabase.MMS_ID,
AttachmentDatabase.SIZE,
AttachmentDatabase.FILE_NAME,
AttachmentDatabase.DATA,
AttachmentDatabase.THUMBNAIL,
AttachmentDatabase.CONTENT_TYPE,
AttachmentDatabase.CONTENT_LOCATION,
AttachmentDatabase.DIGEST,
AttachmentDatabase.FAST_PREFLIGHT_ID,
AttachmentDatabase.VOICE_NOTE,
AttachmentDatabase.WIDTH,
AttachmentDatabase.HEIGHT,
AttachmentDatabase.CONTENT_DISPOSITION,
AttachmentDatabase.NAME,
AttachmentDatabase.TRANSFER_STATE};
MmsDatabase.QUOTE_ID,
MmsDatabase.QUOTE_AUTHOR,
MmsDatabase.QUOTE_BODY,
MmsDatabase.QUOTE_ATTACHMENT};
String[] smsProjection = {SmsDatabase.DATE_SENT + " AS " + MmsSmsColumns.NORMALIZED_DATE_SENT,
SmsDatabase.DATE_RECEIVED + " AS " + MmsSmsColumns.NORMALIZED_DATE_RECEIVED,
@@ -189,7 +187,7 @@ public class MmsSmsDatabase extends Database {
"'SMS::' || " + MmsSmsColumns.ID
+ " || '::' || " + SmsDatabase.DATE_SENT
+ " AS " + MmsSmsColumns.UNIQUE_ROW_ID,
"NULL AS " + AttachmentDatabase.ATTACHMENT_ID_ALIAS,
"NULL AS " + AttachmentDatabase.ATTACHMENT_JSON_ALIAS,
SmsDatabase.BODY, MmsSmsColumns.READ, MmsSmsColumns.THREAD_ID,
SmsDatabase.TYPE, SmsDatabase.ADDRESS, SmsDatabase.ADDRESS_DEVICE_ID, SmsDatabase.SUBJECT, MmsDatabase.MESSAGE_TYPE,
MmsDatabase.MESSAGE_BOX, SmsDatabase.STATUS, MmsDatabase.PART_COUNT,
@@ -200,22 +198,10 @@ public class MmsSmsDatabase extends Database {
MmsSmsColumns.SUBSCRIPTION_ID, MmsSmsColumns.EXPIRES_IN, MmsSmsColumns.EXPIRE_STARTED,
MmsSmsColumns.NOTIFIED,
MmsDatabase.NETWORK_FAILURE, TRANSPORT,
AttachmentDatabase.UNIQUE_ID,
AttachmentDatabase.MMS_ID,
AttachmentDatabase.SIZE,
AttachmentDatabase.FILE_NAME,
AttachmentDatabase.DATA,
AttachmentDatabase.THUMBNAIL,
AttachmentDatabase.CONTENT_TYPE,
AttachmentDatabase.CONTENT_LOCATION,
AttachmentDatabase.DIGEST,
AttachmentDatabase.FAST_PREFLIGHT_ID,
AttachmentDatabase.VOICE_NOTE,
AttachmentDatabase.WIDTH,
AttachmentDatabase.HEIGHT,
AttachmentDatabase.CONTENT_DISPOSITION,
AttachmentDatabase.NAME,
AttachmentDatabase.TRANSFER_STATE};
MmsDatabase.QUOTE_ID,
MmsDatabase.QUOTE_AUTHOR,
MmsDatabase.QUOTE_BODY,
MmsDatabase.QUOTE_ATTACHMENT};
SQLiteQueryBuilder mmsQueryBuilder = new SQLiteQueryBuilder();
SQLiteQueryBuilder smsQueryBuilder = new SQLiteQueryBuilder();
@@ -226,11 +212,7 @@ public class MmsSmsDatabase extends Database {
smsQueryBuilder.setTables(SmsDatabase.TABLE_NAME);
mmsQueryBuilder.setTables(MmsDatabase.TABLE_NAME + " LEFT OUTER JOIN " +
AttachmentDatabase.TABLE_NAME +
" ON " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.ROW_ID + " = " +
" (SELECT " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.ROW_ID +
" FROM " + AttachmentDatabase.TABLE_NAME + " WHERE " +
AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.MMS_ID + " = " +
MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID + " LIMIT 1)");
" ON " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.MMS_ID + " = " + MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID);
Set<String> mmsColumnsPresent = new HashSet<>();
@@ -273,9 +255,15 @@ public class MmsSmsDatabase extends Database {
mmsColumnsPresent.add(AttachmentDatabase.VOICE_NOTE);
mmsColumnsPresent.add(AttachmentDatabase.WIDTH);
mmsColumnsPresent.add(AttachmentDatabase.HEIGHT);
mmsColumnsPresent.add(AttachmentDatabase.QUOTE);
mmsColumnsPresent.add(AttachmentDatabase.CONTENT_DISPOSITION);
mmsColumnsPresent.add(AttachmentDatabase.NAME);
mmsColumnsPresent.add(AttachmentDatabase.TRANSFER_STATE);
mmsColumnsPresent.add(AttachmentDatabase.ATTACHMENT_JSON_ALIAS);
mmsColumnsPresent.add(MmsDatabase.QUOTE_ID);
mmsColumnsPresent.add(MmsDatabase.QUOTE_AUTHOR);
mmsColumnsPresent.add(MmsDatabase.QUOTE_BODY);
mmsColumnsPresent.add(MmsDatabase.QUOTE_ATTACHMENT);
Set<String> smsColumnsPresent = new HashSet<>();
smsColumnsPresent.add(MmsSmsColumns.ID);
@@ -298,7 +286,7 @@ public class MmsSmsDatabase extends Database {
smsColumnsPresent.add(SmsDatabase.STATUS);
@SuppressWarnings("deprecation")
String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery(TRANSPORT, mmsProjection, mmsColumnsPresent, 4, MMS_TRANSPORT, selection, null, null, null);
String mmsSubQuery = mmsQueryBuilder.buildUnionSubQuery(TRANSPORT, mmsProjection, mmsColumnsPresent, 4, MMS_TRANSPORT, selection, null, MmsDatabase.TABLE_NAME + "." + MmsDatabase.ID, null);
@SuppressWarnings("deprecation")
String smsSubQuery = smsQueryBuilder.buildUnionSubQuery(TRANSPORT, smsProjection, smsColumnsPresent, 4, SMS_TRANSPORT, selection, null, null, null);

View File

@@ -38,7 +38,7 @@ public class PagingMediaLoader extends AsyncLoader<Pair<Cursor, Integer>> {
Cursor cursor = DatabaseFactory.getMediaDatabase(getContext()).getGalleryMediaForThread(threadId);
while (cursor != null && cursor.moveToNext()) {
AttachmentId attachmentId = new AttachmentId(cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentDatabase.ATTACHMENT_ID_ALIAS)), cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentDatabase.UNIQUE_ID)));
AttachmentId attachmentId = new AttachmentId(cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentDatabase.ROW_ID)), cursor.getLong(cursor.getColumnIndexOrThrow(AttachmentDatabase.UNIQUE_ID)));
Uri attachmentUri = PartAuthority.getAttachmentDataUri(attachmentId);
if (attachmentUri.equals(uri)) {

View File

@@ -18,6 +18,7 @@ package org.thoughtcrime.securesms.database.model;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.SpannableString;
import org.thoughtcrime.securesms.R;
@@ -52,11 +53,12 @@ public class MediaMmsMessageRecord extends MmsMessageRecord {
int partCount, long mailbox,
List<IdentityKeyMismatch> mismatches,
List<NetworkFailure> failures, int subscriptionId,
long expiresIn, long expireStarted, int readReceiptCount)
long expiresIn, long expireStarted, int readReceiptCount,
@Nullable Quote quote)
{
super(context, id, body, conversationRecipient, individualRecipient, recipientDeviceId, dateSent,
dateReceived, threadId, Status.STATUS_NONE, deliveryReceiptCount, mailbox, mismatches, failures,
subscriptionId, expiresIn, expireStarted, slideDeck, readReceiptCount);
subscriptionId, expiresIn, expireStarted, slideDeck, readReceiptCount, quote);
this.context = context.getApplicationContext();
this.partCount = partCount;

View File

@@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.database.model;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import org.thoughtcrime.securesms.database.documents.IdentityKeyMismatch;
import org.thoughtcrime.securesms.database.documents.NetworkFailure;
@@ -14,17 +15,21 @@ import java.util.List;
public abstract class MmsMessageRecord extends MessageRecord {
private final @NonNull SlideDeck slideDeck;
private final @NonNull SlideDeck slideDeck;
private final @Nullable Quote quote;
MmsMessageRecord(Context context, long id, String body, Recipient conversationRecipient,
Recipient individualRecipient, int recipientDeviceId, long dateSent,
long dateReceived, long threadId, int deliveryStatus, int deliveryReceiptCount,
long type, List<IdentityKeyMismatch> mismatches,
List<NetworkFailure> networkFailures, int subscriptionId, long expiresIn,
long expireStarted, @NonNull SlideDeck slideDeck, int readReceiptCount)
long expireStarted, @NonNull SlideDeck slideDeck, int readReceiptCount,
@Nullable Quote quote)
{
super(context, id, body, conversationRecipient, individualRecipient, recipientDeviceId, dateSent, dateReceived, threadId, deliveryStatus, deliveryReceiptCount, type, mismatches, networkFailures, subscriptionId, expiresIn, expireStarted, readReceiptCount);
this.slideDeck = slideDeck;
this.quote = quote;
}
@Override
@@ -52,5 +57,7 @@ public abstract class MmsMessageRecord extends MessageRecord {
return slideDeck.containsMediaSlide();
}
public @Nullable Quote getQuote() {
return quote;
}
}

View File

@@ -55,7 +55,7 @@ public class NotificationMmsMessageRecord extends MmsMessageRecord {
super(context, id, "", conversationRecipient, individualRecipient, recipientDeviceId,
dateSent, dateReceived, threadId, Status.STATUS_NONE, deliveryReceiptCount, mailbox,
new LinkedList<IdentityKeyMismatch>(), new LinkedList<NetworkFailure>(), subscriptionId,
0, 0, slideDeck, readReceiptCount);
0, 0, slideDeck, readReceiptCount, null);
this.contentLocation = contentLocation;
this.messageSize = messageSize;

View File

@@ -0,0 +1,39 @@
package org.thoughtcrime.securesms.database.model;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import org.thoughtcrime.securesms.database.Address;
import org.thoughtcrime.securesms.mms.SlideDeck;
public class Quote {
private final long id;
private final Address author;
private final String text;
private final SlideDeck attachment;
public Quote(long id, @NonNull Address author, @Nullable String text, @NonNull SlideDeck attachment) {
this.id = id;
this.author = author;
this.text = text;
this.attachment = attachment;
}
public long getId() {
return id;
}
public @NonNull Address getAuthor() {
return author;
}
public @Nullable String getText() {
return text;
}
public @NonNull SlideDeck getAttachment() {
return attachment;
}
}