Re-use recently-acquired attachment pointers.

fork-5.53.8
Greyson Parrelli 2020-03-27 20:36:06 -04:00
rodzic 9b0954a898
commit d6000af843
21 zmienionych plików z 162 dodań i 138 usunięć

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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;

Wyświetl plik

@ -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

Wyświetl plik

@ -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));

Wyświetl plik

@ -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

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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;
}

Wyświetl plik

@ -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 + ", "

Wyświetl plik

@ -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)

Wyświetl plik

@ -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,

Wyświetl plik

@ -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();

Wyświetl plik

@ -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);

Wyświetl plik

@ -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) -> {

Wyświetl plik

@ -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);

Wyświetl plik

@ -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;

Wyświetl plik

@ -381,7 +381,8 @@ public class SignalServiceMessageSender {
attachment.getFileName(),
attachment.getVoiceNote(),
attachment.getCaption(),
attachment.getBlurHash());
attachment.getBlurHash(),
attachment.getUploadTimestamp());
}

Wyświetl plik

@ -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,

Wyświetl plik

@ -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;
}
}

Wyświetl plik

@ -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;
}
}

Wyświetl plik

@ -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);

Wyświetl plik

@ -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 {