kopia lustrzana https://github.com/ryukoposting/Signal-Android
Re-use recently-acquired attachment pointers.
rodzic
9b0954a898
commit
d6000af843
|
@ -35,10 +35,10 @@ public abstract class Attachment {
|
|||
private final String fastPreflightId;
|
||||
|
||||
private final boolean voiceNote;
|
||||
private final int width;
|
||||
private final int height;
|
||||
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final boolean quote;
|
||||
private final long uploadTimestamp;
|
||||
|
||||
@Nullable
|
||||
private final String caption;
|
||||
|
@ -55,8 +55,9 @@ public abstract class Attachment {
|
|||
public Attachment(@NonNull String contentType, int transferState, long size, @Nullable String fileName,
|
||||
@Nullable String location, @Nullable String key, @Nullable String relay,
|
||||
@Nullable byte[] digest, @Nullable String fastPreflightId, boolean voiceNote,
|
||||
int width, int height, boolean quote, @Nullable String caption, @Nullable StickerLocator stickerLocator,
|
||||
@Nullable BlurHash blurHash, @Nullable TransformProperties transformProperties)
|
||||
int width, int height, boolean quote, long uploadTimestamp, @Nullable String caption,
|
||||
@Nullable StickerLocator stickerLocator, @Nullable BlurHash blurHash,
|
||||
@Nullable TransformProperties transformProperties)
|
||||
{
|
||||
this.contentType = contentType;
|
||||
this.transferState = transferState;
|
||||
|
@ -71,6 +72,7 @@ public abstract class Attachment {
|
|||
this.width = width;
|
||||
this.height = height;
|
||||
this.quote = quote;
|
||||
this.uploadTimestamp = uploadTimestamp;
|
||||
this.stickerLocator = stickerLocator;
|
||||
this.caption = caption;
|
||||
this.blurHash = blurHash;
|
||||
|
@ -147,6 +149,10 @@ public abstract class Attachment {
|
|||
return quote;
|
||||
}
|
||||
|
||||
public long getUploadTimestamp() {
|
||||
return uploadTimestamp;
|
||||
}
|
||||
|
||||
public boolean isSticker() {
|
||||
return stickerLocator != null;
|
||||
}
|
||||
|
|
|
@ -28,9 +28,10 @@ public class DatabaseAttachment extends Attachment {
|
|||
byte[] digest, String fastPreflightId, boolean voiceNote,
|
||||
int width, int height, boolean quote, @Nullable String caption,
|
||||
@Nullable StickerLocator stickerLocator, @Nullable BlurHash blurHash,
|
||||
@Nullable TransformProperties transformProperties, int displayOrder)
|
||||
@Nullable TransformProperties transformProperties, int displayOrder,
|
||||
long uploadTimestamp)
|
||||
{
|
||||
super(contentType, transferProgress, size, fileName, location, key, relay, digest, fastPreflightId, voiceNote, width, height, quote, caption, stickerLocator, blurHash, transformProperties);
|
||||
super(contentType, transferProgress, size, fileName, location, key, relay, digest, fastPreflightId, voiceNote, width, height, quote, uploadTimestamp, caption, stickerLocator, blurHash, transformProperties);
|
||||
this.attachmentId = attachmentId;
|
||||
this.hasData = hasData;
|
||||
this.hasThumbnail = hasThumbnail;
|
||||
|
|
|
@ -10,7 +10,7 @@ import org.thoughtcrime.securesms.database.MmsDatabase;
|
|||
public class MmsNotificationAttachment extends Attachment {
|
||||
|
||||
public MmsNotificationAttachment(int status, long size) {
|
||||
super("application/mms", getTransferStateFromStatus(status), size, null, null, null, null, null, null, false, 0, 0, false, null, null, null, null);
|
||||
super("application/mms", getTransferStateFromStatus(status), size, null, null, null, null, null, null, false, 0, 0, false, 0, null, null, null, null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
|
|
@ -21,10 +21,10 @@ public class PointerAttachment extends Attachment {
|
|||
@Nullable String fileName, @NonNull String location,
|
||||
@Nullable String key, @Nullable String relay,
|
||||
@Nullable byte[] digest, @Nullable String fastPreflightId, boolean voiceNote,
|
||||
int width, int height, @Nullable String caption, @Nullable StickerLocator stickerLocator,
|
||||
int width, int height, long uploadTimestamp, @Nullable String caption, @Nullable StickerLocator stickerLocator,
|
||||
@Nullable BlurHash blurHash)
|
||||
{
|
||||
super(contentType, transferState, size, fileName, location, key, relay, digest, fastPreflightId, voiceNote, width, height, false, caption, stickerLocator, blurHash, null);
|
||||
super(contentType, transferState, size, fileName, location, key, relay, digest, fastPreflightId, voiceNote, width, height, false, uploadTimestamp, caption, stickerLocator, blurHash, null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@ -100,6 +100,7 @@ public class PointerAttachment extends Attachment {
|
|||
pointer.get().asPointer().getVoiceNote(),
|
||||
pointer.get().asPointer().getWidth(),
|
||||
pointer.get().asPointer().getHeight(),
|
||||
pointer.get().asPointer().getUploadTimestamp(),
|
||||
pointer.get().asPointer().getCaption().orNull(),
|
||||
stickerLocator,
|
||||
BlurHash.parseOrNull(pointer.get().asPointer().getBlurHash().orNull())));
|
||||
|
@ -121,6 +122,7 @@ public class PointerAttachment extends Attachment {
|
|||
false,
|
||||
thumbnail != null ? thumbnail.asPointer().getWidth() : 0,
|
||||
thumbnail != null ? thumbnail.asPointer().getHeight() : 0,
|
||||
thumbnail != null ? thumbnail.asPointer().getUploadTimestamp() : 0,
|
||||
thumbnail != null ? thumbnail.asPointer().getCaption().orNull() : null,
|
||||
null,
|
||||
null));
|
||||
|
|
|
@ -16,7 +16,7 @@ import org.thoughtcrime.securesms.database.AttachmentDatabase;
|
|||
public class TombstoneAttachment extends Attachment {
|
||||
|
||||
public TombstoneAttachment(@NonNull String contentType, boolean quote) {
|
||||
super(contentType, AttachmentDatabase.TRANSFER_PROGRESS_DONE, 0, null, null, null, null, null, null, false, 0, 0, quote, null, null, null, null);
|
||||
super(contentType, AttachmentDatabase.TRANSFER_PROGRESS_DONE, 0, null, null, null, null, null, null, false, 0, 0, quote, 0, null, null, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -27,7 +27,7 @@ public class UriAttachment extends Attachment {
|
|||
boolean voiceNote, boolean quote, @Nullable String caption, @Nullable StickerLocator stickerLocator,
|
||||
@Nullable BlurHash blurHash, @Nullable TransformProperties transformProperties)
|
||||
{
|
||||
super(contentType, transferState, size, fileName, null, null, null, null, fastPreflightId, voiceNote, width, height, quote, caption, stickerLocator, blurHash, transformProperties);
|
||||
super(contentType, transferState, size, fileName, null, null, null, null, fastPreflightId, voiceNote, width, height, quote, 0, caption, stickerLocator, blurHash, transformProperties);
|
||||
this.dataUri = dataUri;
|
||||
this.thumbnailUri = thumbnailUri;
|
||||
}
|
||||
|
|
|
@ -123,6 +123,7 @@ public class AttachmentDatabase extends Database {
|
|||
static final String BLUR_HASH = "blur_hash";
|
||||
static final String TRANSFORM_PROPERTIES = "transform_properties";
|
||||
static final String DISPLAY_ORDER = "display_order";
|
||||
static final String UPLOAD_TIMESTAMP = "upload_timestamp";
|
||||
|
||||
public static final String DIRECTORY = "parts";
|
||||
|
||||
|
@ -144,24 +145,46 @@ public class AttachmentDatabase extends Database {
|
|||
QUOTE, DATA_RANDOM, THUMBNAIL_RANDOM, WIDTH, HEIGHT,
|
||||
CAPTION, STICKER_PACK_ID, STICKER_PACK_KEY, STICKER_ID,
|
||||
DATA_HASH, BLUR_HASH, TRANSFORM_PROPERTIES, TRANSFER_FILE,
|
||||
DISPLAY_ORDER };
|
||||
DISPLAY_ORDER, UPLOAD_TIMESTAMP };
|
||||
|
||||
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ROW_ID + " INTEGER PRIMARY KEY, " +
|
||||
MMS_ID + " INTEGER, " + "seq" + " INTEGER DEFAULT 0, " +
|
||||
CONTENT_TYPE + " TEXT, " + NAME + " TEXT, " + "chset" + " INTEGER, " +
|
||||
CONTENT_DISPOSITION + " TEXT, " + "fn" + " TEXT, " + "cid" + " TEXT, " +
|
||||
CONTENT_LOCATION + " TEXT, " + "ctt_s" + " INTEGER, " +
|
||||
"ctt_t" + " TEXT, " + "encrypted" + " INTEGER, " +
|
||||
TRANSFER_STATE + " INTEGER, "+ DATA + " TEXT, " + SIZE + " INTEGER, " +
|
||||
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, " +
|
||||
QUOTE + " INTEGER DEFAULT 0, " + WIDTH + " INTEGER DEFAULT 0, " + HEIGHT + " INTEGER DEFAULT 0, " +
|
||||
CAPTION + " TEXT DEFAULT NULL, " + STICKER_PACK_ID + " TEXT DEFAULT NULL, " +
|
||||
STICKER_PACK_KEY + " DEFAULT NULL, " + STICKER_ID + " INTEGER DEFAULT -1, " +
|
||||
DATA_HASH + " TEXT DEFAULT NULL, " + BLUR_HASH + " TEXT DEFAULT NULL, " +
|
||||
TRANSFORM_PROPERTIES + " TEXT DEFAULT NULL, " + TRANSFER_FILE + " TEXT DEFAULT NULL, " +
|
||||
DISPLAY_ORDER + " INTEGER DEFAULT 0);";
|
||||
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ROW_ID + " INTEGER PRIMARY KEY, " +
|
||||
MMS_ID + " INTEGER, " +
|
||||
"seq" + " INTEGER DEFAULT 0, " +
|
||||
CONTENT_TYPE + " TEXT, " +
|
||||
NAME + " TEXT, " +
|
||||
"chset" + " INTEGER, " +
|
||||
CONTENT_DISPOSITION + " TEXT, " +
|
||||
"fn" + " TEXT, " +
|
||||
"cid" + " TEXT, " +
|
||||
CONTENT_LOCATION + " TEXT, " +
|
||||
"ctt_s" + " INTEGER, " +
|
||||
"ctt_t" + " TEXT, " +
|
||||
"encrypted" + " INTEGER, " +
|
||||
TRANSFER_STATE + " INTEGER, " +
|
||||
DATA + " TEXT, " +
|
||||
SIZE + " INTEGER, " +
|
||||
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, " +
|
||||
QUOTE + " INTEGER DEFAULT 0, " +
|
||||
WIDTH + " INTEGER DEFAULT 0, " +
|
||||
HEIGHT + " INTEGER DEFAULT 0, " +
|
||||
CAPTION + " TEXT DEFAULT NULL, " +
|
||||
STICKER_PACK_ID + " TEXT DEFAULT NULL, " +
|
||||
STICKER_PACK_KEY + " DEFAULT NULL, " +
|
||||
STICKER_ID + " INTEGER DEFAULT -1, " +
|
||||
DATA_HASH + " TEXT DEFAULT NULL, " +
|
||||
BLUR_HASH + " TEXT DEFAULT NULL, " +
|
||||
TRANSFORM_PROPERTIES + " TEXT DEFAULT NULL, " +
|
||||
TRANSFER_FILE + " TEXT DEFAULT NULL, " +
|
||||
DISPLAY_ORDER + " INTEGER DEFAULT 0, " +
|
||||
UPLOAD_TIMESTAMP + " INTEGER DEFAULT 0);";
|
||||
|
||||
public static final String[] CREATE_INDEXS = {
|
||||
"CREATE INDEX IF NOT EXISTS part_mms_id_index ON " + TABLE_NAME + " (" + MMS_ID + ");",
|
||||
|
@ -601,8 +624,9 @@ public class AttachmentDatabase extends Database {
|
|||
|
||||
}
|
||||
|
||||
public void updateAttachmentAfterUpload(@NonNull AttachmentId id, @NonNull Attachment attachment) {
|
||||
public void updateAttachmentAfterUpload(@NonNull AttachmentId id, @NonNull Attachment attachment, long uploadTimestamp) {
|
||||
SQLiteDatabase database = databaseHelper.getWritableDatabase();
|
||||
DataInfo dataInfo = getAttachmentDataFileInfo(id, DATA);
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
values.put(TRANSFER_STATE, TRANSFER_PROGRESS_DONE);
|
||||
|
@ -613,8 +637,13 @@ public class AttachmentDatabase extends Database {
|
|||
values.put(SIZE, attachment.getSize());
|
||||
values.put(FAST_PREFLIGHT_ID, attachment.getFastPreflightId());
|
||||
values.put(BLUR_HASH, getBlurHashStringOrNull(attachment.getBlurHash()));
|
||||
values.put(UPLOAD_TIMESTAMP, uploadTimestamp);
|
||||
|
||||
database.update(TABLE_NAME, values, PART_ID_WHERE, id.toStrings());
|
||||
if (dataInfo != null && dataInfo.hash != null) {
|
||||
updateAttachmentAndMatchingHashes(database, id, dataInfo.hash, values);
|
||||
} else {
|
||||
database.update(TABLE_NAME, values, PART_ID_WHERE, id.toStrings());
|
||||
}
|
||||
}
|
||||
|
||||
public @NonNull DatabaseAttachment insertAttachmentForPreUpload(@NonNull Attachment attachment) throws MmsException {
|
||||
|
@ -1093,7 +1122,8 @@ public class AttachmentDatabase extends Database {
|
|||
: null,
|
||||
BlurHash.parseOrNull(object.getString(BLUR_HASH)),
|
||||
TransformProperties.parse(object.getString(TRANSFORM_PROPERTIES)),
|
||||
object.getInt(DISPLAY_ORDER)));
|
||||
object.getInt(DISPLAY_ORDER),
|
||||
object.getLong(UPLOAD_TIMESTAMP)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1125,7 +1155,8 @@ public class AttachmentDatabase extends Database {
|
|||
: null,
|
||||
BlurHash.parseOrNull(cursor.getString(cursor.getColumnIndexOrThrow(BLUR_HASH))),
|
||||
TransformProperties.parse(cursor.getString(cursor.getColumnIndexOrThrow(TRANSFORM_PROPERTIES))),
|
||||
cursor.getInt(cursor.getColumnIndexOrThrow(DISPLAY_ORDER))));
|
||||
cursor.getInt(cursor.getColumnIndexOrThrow(DISPLAY_ORDER)),
|
||||
cursor.getLong(cursor.getColumnIndexOrThrow(UPLOAD_TIMESTAMP))));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
throw new AssertionError(e);
|
||||
|
@ -1159,15 +1190,17 @@ public class AttachmentDatabase extends Database {
|
|||
}
|
||||
}
|
||||
|
||||
boolean useTemplateUpload = template.getUploadTimestamp() > attachment.getUploadTimestamp() && template.getTransferState() == TRANSFER_PROGRESS_DONE;
|
||||
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(MMS_ID, mmsId);
|
||||
contentValues.put(CONTENT_TYPE, template.getContentType());
|
||||
contentValues.put(TRANSFER_STATE, attachment.getTransferState());
|
||||
contentValues.put(UNIQUE_ID, uniqueId);
|
||||
contentValues.put(CONTENT_LOCATION, attachment.getLocation());
|
||||
contentValues.put(DIGEST, attachment.getDigest());
|
||||
contentValues.put(CONTENT_DISPOSITION, attachment.getKey());
|
||||
contentValues.put(NAME, attachment.getRelay());
|
||||
contentValues.put(CONTENT_LOCATION, useTemplateUpload ? template.getLocation() : attachment.getLocation());
|
||||
contentValues.put(DIGEST, useTemplateUpload ? template.getDigest() : attachment.getDigest());
|
||||
contentValues.put(CONTENT_DISPOSITION, useTemplateUpload ? template.getKey() : attachment.getKey());
|
||||
contentValues.put(NAME, useTemplateUpload ? template.getRelay() : attachment.getRelay());
|
||||
contentValues.put(FILE_NAME, StorageUtil.getCleanFileName(attachment.getFileName()));
|
||||
contentValues.put(SIZE, template.getSize());
|
||||
contentValues.put(FAST_PREFLIGHT_ID, attachment.getFastPreflightId());
|
||||
|
@ -1176,12 +1209,13 @@ public class AttachmentDatabase extends Database {
|
|||
contentValues.put(HEIGHT, template.getHeight());
|
||||
contentValues.put(QUOTE, quote);
|
||||
contentValues.put(CAPTION, attachment.getCaption());
|
||||
contentValues.put(UPLOAD_TIMESTAMP, useTemplateUpload ? template.getUploadTimestamp() : attachment.getUploadTimestamp());
|
||||
if (attachment.getTransformProperties().isVideoEdited()) {
|
||||
contentValues.putNull(BLUR_HASH);
|
||||
contentValues.put(TRANSFORM_PROPERTIES, attachment.getTransformProperties().serialize());
|
||||
thumbnailTimeUs = Math.max(STANDARD_THUMB_TIME, attachment.getTransformProperties().videoTrimStartTimeUs);
|
||||
} else {
|
||||
contentValues.put(BLUR_HASH, getBlurHashStringOrNull(attachment.getBlurHash()));
|
||||
contentValues.put(BLUR_HASH, getBlurHashStringOrNull(template.getBlurHash()));
|
||||
contentValues.put(TRANSFORM_PROPERTIES, template.getTransformProperties().serialize());
|
||||
thumbnailTimeUs = STANDARD_THUMB_TIME;
|
||||
}
|
||||
|
|
|
@ -47,6 +47,7 @@ public class MediaDatabase extends Database {
|
|||
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.DISPLAY_ORDER + ", "
|
||||
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.CAPTION + ", "
|
||||
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.NAME + ", "
|
||||
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.UPLOAD_TIMESTAMP + ", "
|
||||
+ MmsDatabase.TABLE_NAME + "." + MmsDatabase.MESSAGE_BOX + ", "
|
||||
+ MmsDatabase.TABLE_NAME + "." + MmsDatabase.DATE_SENT + ", "
|
||||
+ MmsDatabase.TABLE_NAME + "." + MmsDatabase.DATE_RECEIVED + ", "
|
||||
|
|
|
@ -213,7 +213,8 @@ public class MmsDatabase extends MessagingDatabase {
|
|||
"'" + AttachmentDatabase.STICKER_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.STICKER_ID + ", " +
|
||||
"'" + AttachmentDatabase.BLUR_HASH + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.BLUR_HASH + ", " +
|
||||
"'" + AttachmentDatabase.TRANSFORM_PROPERTIES + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.TRANSFORM_PROPERTIES + ", " +
|
||||
"'" + AttachmentDatabase.DISPLAY_ORDER + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.DISPLAY_ORDER +
|
||||
"'" + AttachmentDatabase.DISPLAY_ORDER + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.DISPLAY_ORDER + ", " +
|
||||
"'" + AttachmentDatabase.UPLOAD_TIMESTAMP + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.UPLOAD_TIMESTAMP +
|
||||
")) AS " + AttachmentDatabase.ATTACHMENT_JSON_ALIAS,
|
||||
};
|
||||
|
||||
|
@ -887,59 +888,6 @@ public class MmsDatabase extends MessagingDatabase {
|
|||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
public long copyMessageInbox(long messageId) throws MmsException {
|
||||
try {
|
||||
OutgoingMediaMessage request = getOutgoingMessage(messageId);
|
||||
ContentValues contentValues = new ContentValues();
|
||||
contentValues.put(RECIPIENT_ID, request.getRecipient().getId().serialize());
|
||||
contentValues.put(DATE_SENT, request.getSentTimeMillis());
|
||||
contentValues.put(MESSAGE_BOX, Types.BASE_INBOX_TYPE | Types.SECURE_MESSAGE_BIT);
|
||||
contentValues.put(THREAD_ID, getThreadIdForMessage(messageId));
|
||||
contentValues.put(READ, 1);
|
||||
contentValues.put(DATE_RECEIVED, contentValues.getAsLong(DATE_SENT));
|
||||
contentValues.put(EXPIRES_IN, request.getExpiresIn());
|
||||
contentValues.put(VIEW_ONCE, request.isViewOnce());
|
||||
|
||||
List<Attachment> attachments = new LinkedList<>();
|
||||
|
||||
for (Attachment attachment : request.getAttachments()) {
|
||||
DatabaseAttachment databaseAttachment = (DatabaseAttachment)attachment;
|
||||
attachments.add(new DatabaseAttachment(databaseAttachment.getAttachmentId(),
|
||||
databaseAttachment.getMmsId(),
|
||||
databaseAttachment.hasData(),
|
||||
databaseAttachment.hasThumbnail(),
|
||||
databaseAttachment.getContentType(),
|
||||
AttachmentDatabase.TRANSFER_PROGRESS_DONE,
|
||||
databaseAttachment.getSize(),
|
||||
databaseAttachment.getFileName(),
|
||||
databaseAttachment.getLocation(),
|
||||
databaseAttachment.getKey(),
|
||||
databaseAttachment.getRelay(),
|
||||
databaseAttachment.getDigest(),
|
||||
databaseAttachment.getFastPreflightId(),
|
||||
databaseAttachment.isVoiceNote(),
|
||||
databaseAttachment.getWidth(),
|
||||
databaseAttachment.getHeight(),
|
||||
databaseAttachment.isQuote(),
|
||||
databaseAttachment.getCaption(),
|
||||
databaseAttachment.getSticker(),
|
||||
databaseAttachment.getBlurHash(),
|
||||
databaseAttachment.getTransformProperties(),
|
||||
databaseAttachment.getDisplayOrder()));
|
||||
}
|
||||
|
||||
return insertMediaMessage(request.getBody(),
|
||||
attachments,
|
||||
new LinkedList<>(),
|
||||
request.getSharedContacts(),
|
||||
request.getLinkPreviews(),
|
||||
contentValues,
|
||||
null);
|
||||
} catch (NoSuchMessageException e) {
|
||||
throw new MmsException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private Optional<InsertResult> insertMessageInbox(IncomingMediaMessage retrieved,
|
||||
String contentLocation,
|
||||
long threadId, long mailbox)
|
||||
|
|
|
@ -361,7 +361,8 @@ public class MmsSmsDatabase extends Database {
|
|||
"'" + AttachmentDatabase.STICKER_ID + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.STICKER_ID + ", " +
|
||||
"'" + AttachmentDatabase.BLUR_HASH + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.BLUR_HASH + ", " +
|
||||
"'" + AttachmentDatabase.TRANSFORM_PROPERTIES + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.TRANSFORM_PROPERTIES + ", " +
|
||||
"'" + AttachmentDatabase.DISPLAY_ORDER + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.DISPLAY_ORDER +
|
||||
"'" + AttachmentDatabase.DISPLAY_ORDER + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.DISPLAY_ORDER + ", " +
|
||||
"'" + AttachmentDatabase.UPLOAD_TIMESTAMP + "', " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.UPLOAD_TIMESTAMP +
|
||||
")) AS " + AttachmentDatabase.ATTACHMENT_JSON_ALIAS,
|
||||
SmsDatabase.BODY, MmsSmsColumns.READ, MmsSmsColumns.THREAD_ID,
|
||||
SmsDatabase.TYPE, SmsDatabase.RECIPIENT_ID, SmsDatabase.ADDRESS_DEVICE_ID, SmsDatabase.SUBJECT, MmsDatabase.MESSAGE_TYPE,
|
||||
|
|
|
@ -125,8 +125,9 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
|||
private static final int PROFILE_DATA_MIGRATION = 53;
|
||||
private static final int AVATAR_LOCATION_MIGRATION = 54;
|
||||
private static final int GROUPS_V2 = 55;
|
||||
private static final int ATTACHMENT_UPLOAD_TIMESTAMP = 56;
|
||||
|
||||
private static final int DATABASE_VERSION = 55;
|
||||
private static final int DATABASE_VERSION = 56;
|
||||
private static final String DATABASE_NAME = "signal.db";
|
||||
|
||||
private final Context context;
|
||||
|
@ -858,6 +859,10 @@ public class SQLCipherOpenHelper extends SQLiteOpenHelper {
|
|||
db.execSQL("ALTER TABLE groups ADD COLUMN decrypted_group");
|
||||
}
|
||||
|
||||
if (oldVersion < ATTACHMENT_UPLOAD_TIMESTAMP) {
|
||||
db.execSQL("ALTER TABLE part ADD COLUMN upload_timestamp DEFAULT 0");
|
||||
}
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
|
|
|
@ -204,24 +204,14 @@ public class AttachmentDownloadJob extends BaseJob {
|
|||
Optional.fromNullable(attachment.getFileName()),
|
||||
attachment.isVoiceNote(),
|
||||
Optional.absent(),
|
||||
Optional.fromNullable(attachment.getBlurHash()).transform(BlurHash::getHash));
|
||||
Optional.fromNullable(attachment.getBlurHash()).transform(BlurHash::getHash),
|
||||
attachment.getUploadTimestamp());
|
||||
} catch (IOException | ArithmeticException e) {
|
||||
Log.w(TAG, e);
|
||||
throw new InvalidPartException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private File createTempFile() throws InvalidPartException {
|
||||
try {
|
||||
File file = File.createTempFile("push-attachment", "tmp", context.getCacheDir());
|
||||
file.deleteOnExit();
|
||||
|
||||
return file;
|
||||
} catch (IOException e) {
|
||||
throw new InvalidPartException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void markFailed(long messageId, AttachmentId attachmentId) {
|
||||
try {
|
||||
AttachmentDatabase database = DatabaseFactory.getAttachmentDatabase(context);
|
||||
|
|
|
@ -49,6 +49,8 @@ public final class AttachmentUploadJob extends BaseJob {
|
|||
@SuppressWarnings("unused")
|
||||
private static final String TAG = Log.tag(AttachmentUploadJob.class);
|
||||
|
||||
private static final long UPLOAD_REUSE_THRESHOLD = TimeUnit.DAYS.toMillis(3);
|
||||
|
||||
private static final String KEY_ROW_ID = "row_id";
|
||||
private static final String KEY_UNIQUE_ID = "unique_id";
|
||||
|
||||
|
@ -95,6 +97,14 @@ public final class AttachmentUploadJob extends BaseJob {
|
|||
throw new InvalidAttachmentException("Cannot find the specified attachment.");
|
||||
}
|
||||
|
||||
long timeSinceUpload = System.currentTimeMillis() - databaseAttachment.getUploadTimestamp();
|
||||
if (timeSinceUpload < UPLOAD_REUSE_THRESHOLD) {
|
||||
Log.i(TAG, "We can re-use an already-uploaded file. It was uploaded " + timeSinceUpload + " ms ago. Skipping.");
|
||||
return;
|
||||
} else if (databaseAttachment.getUploadTimestamp() > 0) {
|
||||
Log.i(TAG, "This file was previously-uploaded, but too long ago to be re-used. Age: " + timeSinceUpload + " ms");
|
||||
}
|
||||
|
||||
Log.i(TAG, "Uploading attachment for message " + databaseAttachment.getMmsId() + " with ID " + databaseAttachment.getAttachmentId());
|
||||
|
||||
try (NotificationController notification = getNotificationForAttachment(databaseAttachment)) {
|
||||
|
@ -102,7 +112,7 @@ public final class AttachmentUploadJob extends BaseJob {
|
|||
SignalServiceAttachmentPointer remoteAttachment = messageSender.uploadAttachment(localAttachment.asStream());
|
||||
Attachment attachment = PointerAttachment.forPointer(Optional.of(remoteAttachment), null, databaseAttachment.getFastPreflightId()).get();
|
||||
|
||||
database.updateAttachmentAfterUpload(databaseAttachment.getAttachmentId(), attachment);
|
||||
database.updateAttachmentAfterUpload(databaseAttachment.getAttachmentId(), attachment, remoteAttachment.getUploadTimestamp());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -138,6 +148,7 @@ public final class AttachmentUploadJob extends BaseJob {
|
|||
.withVoiceNote(attachment.isVoiceNote())
|
||||
.withWidth(attachment.getWidth())
|
||||
.withHeight(attachment.getHeight())
|
||||
.withUploadTimestamp(System.currentTimeMillis())
|
||||
.withCaption(attachment.getCaption())
|
||||
.withCancelationSignal(this::isCanceled)
|
||||
.withListener((total, progress) -> {
|
||||
|
|
|
@ -90,7 +90,7 @@ public class AvatarDownloadJob extends BaseJob {
|
|||
attachment.deleteOnExit();
|
||||
|
||||
SignalServiceMessageReceiver receiver = ApplicationDependencies.getSignalServiceMessageReceiver();
|
||||
SignalServiceAttachmentPointer pointer = new SignalServiceAttachmentPointer(avatarId, contentType, key, Optional.of(0), Optional.absent(), 0, 0, digest, fileName, false, Optional.absent(), Optional.absent());
|
||||
SignalServiceAttachmentPointer pointer = new SignalServiceAttachmentPointer(avatarId, contentType, key, Optional.of(0), Optional.absent(), 0, 0, digest, fileName, false, Optional.absent(), Optional.absent(), System.currentTimeMillis());
|
||||
InputStream inputStream = receiver.retrieveAttachment(pointer, attachment, AvatarHelper.AVATAR_DOWNLOAD_FAILSAFE_MAX_SIZE);
|
||||
|
||||
AvatarHelper.setAvatar(context, record.get().getRecipientId(), inputStream);
|
||||
|
|
|
@ -198,7 +198,8 @@ public abstract class PushSendJob extends SendJob {
|
|||
Optional.fromNullable(attachment.getFileName()),
|
||||
attachment.isVoiceNote(),
|
||||
Optional.fromNullable(attachment.getCaption()),
|
||||
Optional.fromNullable(attachment.getBlurHash()).transform(BlurHash::getHash));
|
||||
Optional.fromNullable(attachment.getBlurHash()).transform(BlurHash::getHash),
|
||||
attachment.getUploadTimestamp());
|
||||
} catch (IOException | ArithmeticException e) {
|
||||
Log.w(TAG, e);
|
||||
return null;
|
||||
|
|
|
@ -381,7 +381,8 @@ public class SignalServiceMessageSender {
|
|||
attachment.getFileName(),
|
||||
attachment.getVoiceNote(),
|
||||
attachment.getCaption(),
|
||||
attachment.getBlurHash());
|
||||
attachment.getBlurHash(),
|
||||
attachment.getUploadTimestamp());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ public abstract class SignalServiceAttachment {
|
|||
private int height;
|
||||
private String caption;
|
||||
private String blurHash;
|
||||
private long uploadTimestamp;
|
||||
|
||||
private Builder() {}
|
||||
|
||||
|
@ -109,6 +110,11 @@ public abstract class SignalServiceAttachment {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder withUploadTimestamp(long uploadTimestamp) {
|
||||
this.uploadTimestamp = uploadTimestamp;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SignalServiceAttachmentStream build() {
|
||||
if (inputStream == null) throw new IllegalArgumentException("Must specify stream!");
|
||||
if (contentType == null) throw new IllegalArgumentException("No content type specified!");
|
||||
|
@ -122,6 +128,7 @@ public abstract class SignalServiceAttachment {
|
|||
Optional.<byte[]>absent(),
|
||||
width,
|
||||
height,
|
||||
uploadTimestamp,
|
||||
Optional.fromNullable(caption),
|
||||
Optional.fromNullable(blurHash),
|
||||
listener,
|
||||
|
|
|
@ -12,7 +12,7 @@ import org.whispersystems.signalservice.api.SignalServiceMessageReceiver;
|
|||
/**
|
||||
* Represents a received SignalServiceAttachment "handle." This
|
||||
* is a pointer to the actual attachment content, which needs to be
|
||||
* retrieved using {@link SignalServiceMessageReceiver#retrieveAttachment(SignalServiceAttachmentPointer, java.io.File, int)}
|
||||
* retrieved using {@link SignalServiceMessageReceiver#retrieveAttachment(SignalServiceAttachmentPointer, java.io.File, long)}
|
||||
*
|
||||
* @author Moxie Marlinspike
|
||||
*/
|
||||
|
@ -29,26 +29,28 @@ public class SignalServiceAttachmentPointer extends SignalServiceAttachment {
|
|||
private final int height;
|
||||
private final Optional<String> caption;
|
||||
private final Optional<String> blurHash;
|
||||
private final long uploadTimestamp;
|
||||
|
||||
public SignalServiceAttachmentPointer(long id, String contentType, byte[] key,
|
||||
Optional<Integer> size, Optional<byte[]> preview,
|
||||
int width, int height,
|
||||
Optional<byte[]> digest, Optional<String> fileName,
|
||||
boolean voiceNote, Optional<String> caption,
|
||||
Optional<String> blurHash)
|
||||
Optional<String> blurHash, long uploadTimestamp)
|
||||
{
|
||||
super(contentType);
|
||||
this.id = id;
|
||||
this.key = key;
|
||||
this.size = size;
|
||||
this.preview = preview;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.digest = digest;
|
||||
this.fileName = fileName;
|
||||
this.voiceNote = voiceNote;
|
||||
this.caption = caption;
|
||||
this.blurHash = blurHash;
|
||||
this.id = id;
|
||||
this.key = key;
|
||||
this.size = size;
|
||||
this.preview = preview;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.digest = digest;
|
||||
this.fileName = fileName;
|
||||
this.voiceNote = voiceNote;
|
||||
this.caption = caption;
|
||||
this.blurHash = blurHash;
|
||||
this.uploadTimestamp = uploadTimestamp;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
|
@ -104,4 +106,8 @@ public class SignalServiceAttachmentPointer extends SignalServiceAttachment {
|
|||
public Optional<String> getBlurHash() {
|
||||
return blurHash;
|
||||
}
|
||||
|
||||
public long getUploadTimestamp() {
|
||||
return uploadTimestamp;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,11 +25,12 @@ public class SignalServiceAttachmentStream extends SignalServiceAttachment {
|
|||
private final boolean voiceNote;
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final long uploadTimestamp;
|
||||
private final Optional<String> caption;
|
||||
private final Optional<String> blurHash;
|
||||
|
||||
public SignalServiceAttachmentStream(InputStream inputStream, String contentType, long length, Optional<String> fileName, boolean voiceNote, ProgressListener listener, CancelationSignal cancelationSignal) {
|
||||
this(inputStream, contentType, length, fileName, voiceNote, Optional.<byte[]>absent(), 0, 0, Optional.<String>absent(), Optional.<String>absent(), listener, cancelationSignal);
|
||||
this(inputStream, contentType, length, fileName, voiceNote, Optional.<byte[]>absent(), 0, 0, System.currentTimeMillis(), Optional.<String>absent(), Optional.<String>absent(), listener, cancelationSignal);
|
||||
}
|
||||
|
||||
public SignalServiceAttachmentStream(InputStream inputStream,
|
||||
|
@ -40,6 +41,7 @@ public class SignalServiceAttachmentStream extends SignalServiceAttachment {
|
|||
Optional<byte[]> preview,
|
||||
int width,
|
||||
int height,
|
||||
long uploadTimestamp,
|
||||
Optional<String> caption,
|
||||
Optional<String> blurHash,
|
||||
ProgressListener listener,
|
||||
|
@ -54,6 +56,7 @@ public class SignalServiceAttachmentStream extends SignalServiceAttachment {
|
|||
this.preview = preview;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.uploadTimestamp = uploadTimestamp;
|
||||
this.caption = caption;
|
||||
this.blurHash = blurHash;
|
||||
this.cancelationSignal = cancelationSignal;
|
||||
|
@ -112,4 +115,8 @@ public class SignalServiceAttachmentStream extends SignalServiceAttachment {
|
|||
public Optional<String> getBlurHash() {
|
||||
return blurHash;
|
||||
}
|
||||
|
||||
public long getUploadTimestamp() {
|
||||
return uploadTimestamp;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -747,7 +747,8 @@ public final class SignalServiceContent {
|
|||
pointer.hasFileName() ? Optional.of(pointer.getFileName()) : Optional.<String>absent(),
|
||||
(pointer.getFlags() & SignalServiceProtos.AttachmentPointer.Flags.VOICE_MESSAGE_VALUE) != 0,
|
||||
pointer.hasCaption() ? Optional.of(pointer.getCaption()) : Optional.<String>absent(),
|
||||
pointer.hasBlurHash() ? Optional.of(pointer.getBlurHash()) : Optional.<String>absent());
|
||||
pointer.hasBlurHash() ? Optional.of(pointer.getBlurHash()) : Optional.<String>absent(),
|
||||
pointer.hasUploadTimestamp() ? pointer.getUploadTimestamp() : 0);
|
||||
|
||||
}
|
||||
|
||||
|
@ -803,7 +804,8 @@ public final class SignalServiceContent {
|
|||
Optional.<String>absent(),
|
||||
false,
|
||||
Optional.<String>absent(),
|
||||
Optional.<String>absent());
|
||||
Optional.<String>absent(),
|
||||
pointer.hasUploadTimestamp() ? pointer.getUploadTimestamp() : 0);
|
||||
}
|
||||
|
||||
return new SignalServiceGroup(type, content.getGroup().getId().toByteArray(), name, members, avatar);
|
||||
|
|
|
@ -377,18 +377,19 @@ message AttachmentPointer {
|
|||
VOICE_MESSAGE = 1;
|
||||
}
|
||||
|
||||
optional fixed64 id = 1;
|
||||
optional string contentType = 2;
|
||||
optional bytes key = 3;
|
||||
optional uint32 size = 4;
|
||||
optional bytes thumbnail = 5;
|
||||
optional bytes digest = 6;
|
||||
optional string fileName = 7;
|
||||
optional uint32 flags = 8;
|
||||
optional uint32 width = 9;
|
||||
optional uint32 height = 10;
|
||||
optional string caption = 11;
|
||||
optional string blurHash = 12;
|
||||
optional fixed64 id = 1;
|
||||
optional string contentType = 2;
|
||||
optional bytes key = 3;
|
||||
optional uint32 size = 4;
|
||||
optional bytes thumbnail = 5;
|
||||
optional bytes digest = 6;
|
||||
optional string fileName = 7;
|
||||
optional uint32 flags = 8;
|
||||
optional uint32 width = 9;
|
||||
optional uint32 height = 10;
|
||||
optional string caption = 11;
|
||||
optional string blurHash = 12;
|
||||
optional uint64 uploadTimestamp = 13;
|
||||
}
|
||||
|
||||
message GroupContext {
|
||||
|
|
Ładowanie…
Reference in New Issue