Keep track of when audio attachments are voice notes

// FREEBIE
This commit is contained in:
Moxie Marlinspike 2017-05-11 22:46:35 -07:00
parent e96bf2bdc7
commit b78c05e70b
26 changed files with 76 additions and 44 deletions

View File

@ -61,7 +61,7 @@ dependencies {
compile 'org.whispersystems:jobmanager:1.0.2' compile 'org.whispersystems:jobmanager:1.0.2'
compile 'org.whispersystems:libpastelog:1.0.7' compile 'org.whispersystems:libpastelog:1.0.7'
compile 'org.whispersystems:signal-service-android:2.5.5' compile 'org.whispersystems:signal-service-android:2.5.6'
compile 'org.whispersystems:webrtc-android:M57-S2' compile 'org.whispersystems:webrtc-android:M57-S2'
compile "me.leolin:ShortcutBadger:1.1.16" compile "me.leolin:ShortcutBadger:1.1.16"
@ -136,7 +136,7 @@ dependencyVerification {
'com.google.android.exoplayer:exoplayer:955085aa611a8f7cf6c61b88ae03d1a392f4ad94c9bfbc153f3dedb9ffb14718', 'com.google.android.exoplayer:exoplayer:955085aa611a8f7cf6c61b88ae03d1a392f4ad94c9bfbc153f3dedb9ffb14718',
'org.whispersystems:jobmanager:506f679fc2fcf7bb6d10f00f41d6f6ea0abf75c70dc95b913398661ad538a181', 'org.whispersystems:jobmanager:506f679fc2fcf7bb6d10f00f41d6f6ea0abf75c70dc95b913398661ad538a181',
'org.whispersystems:libpastelog:bb331d9a98240fc139101128ba836c1edec3c40e000597cdbb29ebf4cbf34d88', 'org.whispersystems:libpastelog:bb331d9a98240fc139101128ba836c1edec3c40e000597cdbb29ebf4cbf34d88',
'org.whispersystems:signal-service-android:3d7859b194e518fbaf5a082daf22ca345411705e825791f751eb388f149583c3', 'org.whispersystems:signal-service-android:d19edb9faaa59cf9b3550942a030c8fd73d939003cda16955ed6c71209dd4d29',
'org.whispersystems:webrtc-android:9d11e39d4b3823713e5b1486226e0ce09f989d6f47f52da1815e406c186701d5', 'org.whispersystems:webrtc-android:9d11e39d4b3823713e5b1486226e0ce09f989d6f47f52da1815e406c186701d5',
'me.leolin:ShortcutBadger:e3cb3e7625892129b0c92dd5e4bc649faffdd526d5af26d9c45ee31ff8851774', 'me.leolin:ShortcutBadger:e3cb3e7625892129b0c92dd5e4bc649faffdd526d5af26d9c45ee31ff8851774',
'se.emilsjolander:stickylistheaders:a08ca948aa6b220f09d82f16bbbac395f6b78897e9eeac6a9f0b0ba755928eeb', 'se.emilsjolander:stickylistheaders:a08ca948aa6b220f09d82f16bbbac395f6b78897e9eeac6a9f0b0ba755928eeb',
@ -171,23 +171,23 @@ dependencyVerification {
'com.google.android.gms:play-services-base:0ca636a8fc9a5af45e607cdcd61783bf5d561cbbb0f862021ce69606eee5ad49', 'com.google.android.gms:play-services-base:0ca636a8fc9a5af45e607cdcd61783bf5d561cbbb0f862021ce69606eee5ad49',
'com.google.android.gms:play-services-basement:95dd882c5ffba15b9a99de3fefb05d3a01946623af67454ca00055d222f85a8d', 'com.google.android.gms:play-services-basement:95dd882c5ffba15b9a99de3fefb05d3a01946623af67454ca00055d222f85a8d',
'com.google.android.gms:play-services-iid:54e919f9957b8b7820da7ee9b83471d00d0cac1cf08ddea8b5b41aea80bb1a70', 'com.google.android.gms:play-services-iid:54e919f9957b8b7820da7ee9b83471d00d0cac1cf08ddea8b5b41aea80bb1a70',
'org.whispersystems:signal-service-java:a410adf969fc80119f0e04b2c0d4fcec0f9fcca11a098b3782c02925b61dfbad',
'org.whispersystems:signal-protocol-android:1b4b9d557c8eaf861797ff683990d482d4aa8e9f23d9b17ff0cc67a02f38cb19', 'org.whispersystems:signal-protocol-android:1b4b9d557c8eaf861797ff683990d482d4aa8e9f23d9b17ff0cc67a02f38cb19',
'org.whispersystems:signal-service-java:4d51d423510bcc3f3a0db1a2c5c7164e379af7ad7f9c20cf0faa753eef9f3f27',
'com.nineoldandroids:library:68025a14e3e7673d6ad2f95e4b46d78d7d068343aa99256b686fe59de1b3163a', 'com.nineoldandroids:library:68025a14e3e7673d6ad2f95e4b46d78d7d068343aa99256b686fe59de1b3163a',
'javax.inject:javax.inject:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff', 'javax.inject:javax.inject:91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff',
'com.madgag.spongycastle:core:8d6240b974b0aca4d3da9c7dd44d42339d8a374358aca5fc98e50a995764511f', 'com.madgag.spongycastle:core:8d6240b974b0aca4d3da9c7dd44d42339d8a374358aca5fc98e50a995764511f',
'com.klinkerapps:logger:177e325259a8b111ad6745ec10db5861723c99f402222b80629f576f49408541', 'com.klinkerapps:logger:177e325259a8b111ad6745ec10db5861723c99f402222b80629f576f49408541',
'com.google.android.gms:play-services-tasks:69ec265168e601d0203d04cd42e34bb019b2f029aa1e16fabd38a5153eea2086', 'com.google.android.gms:play-services-tasks:69ec265168e601d0203d04cd42e34bb019b2f029aa1e16fabd38a5153eea2086',
'org.whispersystems:curve25519-android:bf6c34223d45d2f2813a8efcab9923caf99115115c760c9acea680bcb42d23c0',
'org.whispersystems:signal-protocol-java:a835cd0609cf116a74651bd0aa748db9392bba48c2d2af787757b8a1b50d131c',
'com.google.protobuf:protobuf-java:e0c1c64575c005601725e7c6a02cebf9e1285e888f756b2a1d73ffa8d725cc74', 'com.google.protobuf:protobuf-java:e0c1c64575c005601725e7c6a02cebf9e1285e888f756b2a1d73ffa8d725cc74',
'com.googlecode.libphonenumber:libphonenumber:141ebcafba7070a13d879c44e7648ddbe10beab665cb64d7b0c1bea93afb8dc2', 'com.googlecode.libphonenumber:libphonenumber:141ebcafba7070a13d879c44e7648ddbe10beab665cb64d7b0c1bea93afb8dc2',
'com.fasterxml.jackson.core:jackson-databind:835097bcdd11f5bc8a08378c70d4c8054dfa4b911691cc2752063c75534d198d', 'com.fasterxml.jackson.core:jackson-databind:835097bcdd11f5bc8a08378c70d4c8054dfa4b911691cc2752063c75534d198d',
'com.squareup.okhttp3:okhttp:a992938d7203ca557cd7a116f002e8c427ec9cdae7ea852441abb8aec891f948', 'com.squareup.okhttp3:okhttp:a992938d7203ca557cd7a116f002e8c427ec9cdae7ea852441abb8aec891f948',
'org.whispersystems:curve25519-java:00f1d4919f759055f41f7853a3d475dc7c8decf0dbf045ae93414f8f23b066cc', 'org.whispersystems:curve25519-android:bf6c34223d45d2f2813a8efcab9923caf99115115c760c9acea680bcb42d23c0',
'org.whispersystems:signal-protocol-java:a835cd0609cf116a74651bd0aa748db9392bba48c2d2af787757b8a1b50d131c',
'com.fasterxml.jackson.core:jackson-annotations:0ca408c24202a7626ec8b861e99d85eca5e38b73311dd6dd12e3e9deecc3fe94', 'com.fasterxml.jackson.core:jackson-annotations:0ca408c24202a7626ec8b861e99d85eca5e38b73311dd6dd12e3e9deecc3fe94',
'com.fasterxml.jackson.core:jackson-core:cbf4604784b4de226262845447a1ad3bb38a6728cebe86562e2c5afada8be2c0', 'com.fasterxml.jackson.core:jackson-core:cbf4604784b4de226262845447a1ad3bb38a6728cebe86562e2c5afada8be2c0',
'com.squareup.okio:okio:8c5436cadfab36bbd97db5f5c43b7bfdb5bf2f5f894ec8709b1929f14bdd010c', 'com.squareup.okio:okio:8c5436cadfab36bbd97db5f5c43b7bfdb5bf2f5f894ec8709b1929f14bdd010c',
'org.whispersystems:curve25519-java:00f1d4919f759055f41f7853a3d475dc7c8decf0dbf045ae93414f8f23b066cc',
'com.android.support:support-annotations:47a2a30eab487a490a8a8f16678007c3d2b6dcae1e09b0485a12bbf921200ec3', 'com.android.support:support-annotations:47a2a30eab487a490a8a8f16678007c3d2b6dcae1e09b0485a12bbf921200ec3',
'com.android.support:support-media-compat:8d6a1a5ba3d9eb1a25cb8f21bb312ac6280202e3d2900cb0b447d065d0d8a125', 'com.android.support:support-media-compat:8d6a1a5ba3d9eb1a25cb8f21bb312ac6280202e3d2900cb0b447d065d0d8a125',
'com.android.support:support-core-utils:a7649e18c04143dde40c218c5ce9a030e7ae674089cd7b18c6cf8ed2a22cf01a', 'com.android.support:support-core-utils:a7649e18c04143dde40c218c5ce9a030e7ae674089cd7b18c6cf8ed2a22cf01a',

View File

@ -1646,7 +1646,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
boolean forceSms = sendButton.isManualSelection() && sendButton.getSelectedTransport().isSms(); boolean forceSms = sendButton.isManualSelection() && sendButton.getSelectedTransport().isSms();
int subscriptionId = sendButton.getSelectedTransport().getSimSubscriptionId().or(-1); int subscriptionId = sendButton.getSelectedTransport().getSimSubscriptionId().or(-1);
long expiresIn = recipients.getExpireMessages() * 1000; long expiresIn = recipients.getExpireMessages() * 1000;
AudioSlide audioSlide = new AudioSlide(ConversationActivity.this, result.first, result.second, MediaUtil.AUDIO_AAC); AudioSlide audioSlide = new AudioSlide(ConversationActivity.this, result.first, result.second, MediaUtil.AUDIO_AAC, true);
SlideDeck slideDeck = new SlideDeck(); SlideDeck slideDeck = new SlideDeck();
slideDeck.addSlide(audioSlide); slideDeck.addSlide(audioSlide);

View File

@ -31,9 +31,11 @@ public abstract class Attachment {
@Nullable @Nullable
private final String fastPreflightId; private final String fastPreflightId;
private final boolean voiceNote;
public Attachment(@NonNull String contentType, int transferState, long size, @Nullable String fileName, public Attachment(@NonNull String contentType, int transferState, long size, @Nullable String fileName,
@Nullable String location, @Nullable String key, @Nullable String relay, @Nullable String location, @Nullable String key, @Nullable String relay,
@Nullable byte[] digest, @Nullable String fastPreflightId) @Nullable byte[] digest, @Nullable String fastPreflightId, boolean voiceNote)
{ {
this.contentType = contentType; this.contentType = contentType;
this.transferState = transferState; this.transferState = transferState;
@ -44,6 +46,7 @@ public abstract class Attachment {
this.relay = relay; this.relay = relay;
this.digest = digest; this.digest = digest;
this.fastPreflightId = fastPreflightId; this.fastPreflightId = fastPreflightId;
this.voiceNote = voiceNote;
} }
@Nullable @Nullable
@ -99,4 +102,8 @@ public abstract class Attachment {
public String getFastPreflightId() { public String getFastPreflightId() {
return fastPreflightId; return fastPreflightId;
} }
public boolean isVoiceNote() {
return voiceNote;
}
} }

View File

@ -16,9 +16,9 @@ public class DatabaseAttachment extends Attachment {
boolean hasData, boolean hasThumbnail, boolean hasData, boolean hasThumbnail,
String contentType, int transferProgress, long size, String contentType, int transferProgress, long size,
String fileName, String location, String key, String relay, String fileName, String location, String key, String relay,
byte[] digest, String fastPreflightId) byte[] digest, String fastPreflightId, boolean voiceNote)
{ {
super(contentType, transferProgress, size, fileName, location, key, relay, digest, fastPreflightId); super(contentType, transferProgress, size, fileName, location, key, relay, digest, fastPreflightId, voiceNote);
this.attachmentId = attachmentId; this.attachmentId = attachmentId;
this.hasData = hasData; this.hasData = hasData;
this.hasThumbnail = hasThumbnail; this.hasThumbnail = hasThumbnail;

View File

@ -10,7 +10,7 @@ import org.thoughtcrime.securesms.database.MmsDatabase;
public class MmsNotificationAttachment extends Attachment { public class MmsNotificationAttachment extends Attachment {
public MmsNotificationAttachment(int status, long size) { public MmsNotificationAttachment(int status, long size) {
super("application/mms", getTransferStateFromStatus(status), size, null, null, null, null, null, null); super("application/mms", getTransferStateFromStatus(status), size, null, null, null, null, null, null, false);
} }
@Nullable @Nullable

View File

@ -18,9 +18,9 @@ public class PointerAttachment extends Attachment {
public PointerAttachment(@NonNull String contentType, int transferState, long size, public PointerAttachment(@NonNull String contentType, int transferState, long size,
@Nullable String fileName, @NonNull String location, @Nullable String fileName, @NonNull String location,
@NonNull String key, @NonNull String relay, @NonNull String key, @NonNull String relay,
@Nullable byte[] digest) @Nullable byte[] digest, boolean voiceNote)
{ {
super(contentType, transferState, size, fileName, location, key, relay, digest, null); super(contentType, transferState, size, fileName, location, key, relay, digest, null, voiceNote);
} }
@Nullable @Nullable
@ -49,7 +49,8 @@ public class PointerAttachment extends Attachment {
pointer.asPointer().getFileName().orNull(), pointer.asPointer().getFileName().orNull(),
String.valueOf(pointer.asPointer().getId()), String.valueOf(pointer.asPointer().getId()),
encryptedKey, pointer.asPointer().getRelay().orNull(), encryptedKey, pointer.asPointer().getRelay().orNull(),
pointer.asPointer().getDigest().orNull())); pointer.asPointer().getDigest().orNull(),
pointer.asPointer().getVoiceNote()));
} }
} }
} }

View File

@ -10,16 +10,17 @@ public class UriAttachment extends Attachment {
private final @Nullable Uri thumbnailUri; private final @Nullable Uri thumbnailUri;
public UriAttachment(@NonNull Uri uri, @NonNull String contentType, int transferState, long size, public UriAttachment(@NonNull Uri uri, @NonNull String contentType, int transferState, long size,
@Nullable String fileName) @Nullable String fileName, boolean voiceNote)
{ {
this(uri, uri, contentType, transferState, size, fileName, null); this(uri, uri, contentType, transferState, size, fileName, null, voiceNote);
} }
public UriAttachment(@NonNull Uri dataUri, @Nullable Uri thumbnailUri, public UriAttachment(@NonNull Uri dataUri, @Nullable Uri thumbnailUri,
@NonNull String contentType, int transferState, long size, @NonNull String contentType, int transferState, long size,
@Nullable String fileName, @Nullable String fastPreflightId) @Nullable String fileName, @Nullable String fastPreflightId,
boolean voiceNote)
{ {
super(contentType, transferState, size, fileName, null, null, null, null, fastPreflightId); super(contentType, transferState, size, fileName, null, null, null, null, fastPreflightId, voiceNote);
this.dataUri = dataUri; this.dataUri = dataUri;
this.thumbnailUri = thumbnailUri; this.thumbnailUri = thumbnailUri;
} }

View File

@ -81,6 +81,7 @@ public class AttachmentDatabase extends Database {
static final String THUMBNAIL_ASPECT_RATIO = "aspect_ratio"; static final String THUMBNAIL_ASPECT_RATIO = "aspect_ratio";
static final String UNIQUE_ID = "unique_id"; static final String UNIQUE_ID = "unique_id";
static final String DIGEST = "digest"; static final String DIGEST = "digest";
static final String VOICE_NOTE = "voice_note";
public static final String FAST_PREFLIGHT_ID = "fast_preflight_id"; public static final String FAST_PREFLIGHT_ID = "fast_preflight_id";
public static final int TRANSFER_PROGRESS_DONE = 0; public static final int TRANSFER_PROGRESS_DONE = 0;
@ -94,7 +95,7 @@ public class AttachmentDatabase extends Database {
MMS_ID, CONTENT_TYPE, NAME, CONTENT_DISPOSITION, MMS_ID, CONTENT_TYPE, NAME, CONTENT_DISPOSITION,
CONTENT_LOCATION, DATA, THUMBNAIL, TRANSFER_STATE, CONTENT_LOCATION, DATA, THUMBNAIL, TRANSFER_STATE,
SIZE, FILE_NAME, THUMBNAIL, THUMBNAIL_ASPECT_RATIO, SIZE, FILE_NAME, THUMBNAIL, THUMBNAIL_ASPECT_RATIO,
UNIQUE_ID, DIGEST, FAST_PREFLIGHT_ID}; UNIQUE_ID, DIGEST, FAST_PREFLIGHT_ID, VOICE_NOTE};
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ROW_ID + " INTEGER PRIMARY KEY, " + public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + " (" + ROW_ID + " INTEGER PRIMARY KEY, " +
MMS_ID + " INTEGER, " + "seq" + " INTEGER DEFAULT 0, " + MMS_ID + " INTEGER, " + "seq" + " INTEGER DEFAULT 0, " +
@ -104,7 +105,8 @@ public class AttachmentDatabase extends Database {
"ctt_t" + " TEXT, " + "encrypted" + " INTEGER, " + "ctt_t" + " TEXT, " + "encrypted" + " INTEGER, " +
TRANSFER_STATE + " INTEGER, "+ DATA + " TEXT, " + SIZE + " INTEGER, " + TRANSFER_STATE + " INTEGER, "+ DATA + " TEXT, " + SIZE + " INTEGER, " +
FILE_NAME + " TEXT, " + THUMBNAIL + " TEXT, " + THUMBNAIL_ASPECT_RATIO + " REAL, " + FILE_NAME + " TEXT, " + THUMBNAIL + " TEXT, " + THUMBNAIL_ASPECT_RATIO + " REAL, " +
UNIQUE_ID + " INTEGER NOT NULL, " + DIGEST + " BLOB, " + FAST_PREFLIGHT_ID + " TEXT);"; UNIQUE_ID + " INTEGER NOT NULL, " + DIGEST + " BLOB, " + FAST_PREFLIGHT_ID + " TEXT, " +
VOICE_NOTE + " INTEGER DEFAULT 0);";
public static final String[] CREATE_INDEXS = { public static final String[] CREATE_INDEXS = {
"CREATE INDEX IF NOT EXISTS part_mms_id_index ON " + TABLE_NAME + " (" + MMS_ID + ");", "CREATE INDEX IF NOT EXISTS part_mms_id_index ON " + TABLE_NAME + " (" + MMS_ID + ");",
@ -332,7 +334,8 @@ public class AttachmentDatabase extends Database {
databaseAttachment.getKey(), databaseAttachment.getKey(),
databaseAttachment.getRelay(), databaseAttachment.getRelay(),
databaseAttachment.getDigest(), databaseAttachment.getDigest(),
databaseAttachment.getFastPreflightId()); databaseAttachment.getFastPreflightId(),
databaseAttachment.isVoiceNote());
} }
@ -484,7 +487,8 @@ public class AttachmentDatabase extends Database {
cursor.getString(cursor.getColumnIndexOrThrow(CONTENT_DISPOSITION)), cursor.getString(cursor.getColumnIndexOrThrow(CONTENT_DISPOSITION)),
cursor.getString(cursor.getColumnIndexOrThrow(NAME)), cursor.getString(cursor.getColumnIndexOrThrow(NAME)),
cursor.getBlob(cursor.getColumnIndexOrThrow(DIGEST)), cursor.getBlob(cursor.getColumnIndexOrThrow(DIGEST)),
cursor.getString(cursor.getColumnIndexOrThrow(FAST_PREFLIGHT_ID))); cursor.getString(cursor.getColumnIndexOrThrow(FAST_PREFLIGHT_ID)),
cursor.getInt(cursor.getColumnIndexOrThrow(VOICE_NOTE)) == 1);
} }
@ -519,6 +523,7 @@ public class AttachmentDatabase extends Database {
contentValues.put(FILE_NAME, fileName); contentValues.put(FILE_NAME, fileName);
contentValues.put(SIZE, attachment.getSize()); contentValues.put(SIZE, attachment.getSize());
contentValues.put(FAST_PREFLIGHT_ID, attachment.getFastPreflightId()); contentValues.put(FAST_PREFLIGHT_ID, attachment.getFastPreflightId());
contentValues.put(VOICE_NOTE, attachment.isVoiceNote() ? 1 : 0);
if (partData != null) { if (partData != null) {
contentValues.put(DATA, partData.first.getAbsolutePath()); contentValues.put(DATA, partData.first.getAbsolutePath());

View File

@ -77,7 +77,8 @@ public class DatabaseFactory {
private static final int INTRODUCED_NOTIFIED = 31; private static final int INTRODUCED_NOTIFIED = 31;
private static final int INTRODUCED_DOCUMENTS = 32; private static final int INTRODUCED_DOCUMENTS = 32;
private static final int INTRODUCED_FAST_PREFLIGHT = 33; private static final int INTRODUCED_FAST_PREFLIGHT = 33;
private static final int DATABASE_VERSION = 33; private static final int INTRODUCED_VOICE_NOTES = 34;
private static final int DATABASE_VERSION = 34;
private static final String DATABASE_NAME = "messages.db"; private static final String DATABASE_NAME = "messages.db";
private static final Object lock = new Object(); private static final Object lock = new Object();
@ -862,6 +863,10 @@ public class DatabaseFactory {
db.execSQL("ALTER TABLE part ADD COLUMN fast_preflight_id TEXT"); db.execSQL("ALTER TABLE part ADD COLUMN fast_preflight_id TEXT");
} }
if (oldVersion < INTRODUCED_VOICE_NOTES) {
db.execSQL("ALTER TABLE part ADD COLUMN voice_note INTEGER DEFAULT 0");
}
db.setTransactionSuccessful(); db.setTransactionSuccessful();
db.endTransaction(); db.endTransaction();
} }

View File

@ -27,6 +27,7 @@ public class MediaDatabase extends Database {
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.CONTENT_DISPOSITION + ", " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.CONTENT_DISPOSITION + ", "
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.DIGEST + ", " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.DIGEST + ", "
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.FAST_PREFLIGHT_ID + ", " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.FAST_PREFLIGHT_ID + ", "
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.VOICE_NOTE + ", "
+ AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.NAME + ", " + AttachmentDatabase.TABLE_NAME + "." + AttachmentDatabase.NAME + ", "
+ MmsDatabase.TABLE_NAME + "." + MmsDatabase.MESSAGE_BOX + ", " + MmsDatabase.TABLE_NAME + "." + MmsDatabase.MESSAGE_BOX + ", "
+ MmsDatabase.TABLE_NAME + "." + MmsDatabase.DATE_SENT + ", " + MmsDatabase.TABLE_NAME + "." + MmsDatabase.DATE_SENT + ", "

View File

@ -147,6 +147,7 @@ public class MmsDatabase extends MessagingDatabase {
AttachmentDatabase.CONTENT_LOCATION, AttachmentDatabase.CONTENT_LOCATION,
AttachmentDatabase.DIGEST, AttachmentDatabase.DIGEST,
AttachmentDatabase.FAST_PREFLIGHT_ID, AttachmentDatabase.FAST_PREFLIGHT_ID,
AttachmentDatabase.VOICE_NOTE,
AttachmentDatabase.CONTENT_DISPOSITION, AttachmentDatabase.CONTENT_DISPOSITION,
AttachmentDatabase.NAME, AttachmentDatabase.NAME,
AttachmentDatabase.TRANSFER_STATE AttachmentDatabase.TRANSFER_STATE
@ -691,7 +692,8 @@ public class MmsDatabase extends MessagingDatabase {
databaseAttachment.getKey(), databaseAttachment.getKey(),
databaseAttachment.getRelay(), databaseAttachment.getRelay(),
databaseAttachment.getDigest(), databaseAttachment.getDigest(),
databaseAttachment.getFastPreflightId())); databaseAttachment.getFastPreflightId(),
databaseAttachment.isVoiceNote()));
} }
return insertMediaMessage(new MasterSecretUnion(masterSecret), return insertMediaMessage(new MasterSecretUnion(masterSecret),

View File

@ -71,6 +71,7 @@ public class MmsSmsDatabase extends Database {
AttachmentDatabase.CONTENT_LOCATION, AttachmentDatabase.CONTENT_LOCATION,
AttachmentDatabase.DIGEST, AttachmentDatabase.DIGEST,
AttachmentDatabase.FAST_PREFLIGHT_ID, AttachmentDatabase.FAST_PREFLIGHT_ID,
AttachmentDatabase.VOICE_NOTE,
AttachmentDatabase.CONTENT_DISPOSITION, AttachmentDatabase.CONTENT_DISPOSITION,
AttachmentDatabase.NAME, AttachmentDatabase.NAME,
AttachmentDatabase.TRANSFER_STATE}; AttachmentDatabase.TRANSFER_STATE};
@ -167,6 +168,7 @@ public class MmsSmsDatabase extends Database {
AttachmentDatabase.CONTENT_LOCATION, AttachmentDatabase.CONTENT_LOCATION,
AttachmentDatabase.DIGEST, AttachmentDatabase.DIGEST,
AttachmentDatabase.FAST_PREFLIGHT_ID, AttachmentDatabase.FAST_PREFLIGHT_ID,
AttachmentDatabase.VOICE_NOTE,
AttachmentDatabase.CONTENT_DISPOSITION, AttachmentDatabase.CONTENT_DISPOSITION,
AttachmentDatabase.NAME, AttachmentDatabase.NAME,
AttachmentDatabase.TRANSFER_STATE}; AttachmentDatabase.TRANSFER_STATE};
@ -197,6 +199,7 @@ public class MmsSmsDatabase extends Database {
AttachmentDatabase.CONTENT_LOCATION, AttachmentDatabase.CONTENT_LOCATION,
AttachmentDatabase.DIGEST, AttachmentDatabase.DIGEST,
AttachmentDatabase.FAST_PREFLIGHT_ID, AttachmentDatabase.FAST_PREFLIGHT_ID,
AttachmentDatabase.VOICE_NOTE,
AttachmentDatabase.CONTENT_DISPOSITION, AttachmentDatabase.CONTENT_DISPOSITION,
AttachmentDatabase.NAME, AttachmentDatabase.NAME,
AttachmentDatabase.TRANSFER_STATE}; AttachmentDatabase.TRANSFER_STATE};
@ -253,6 +256,7 @@ public class MmsSmsDatabase extends Database {
mmsColumnsPresent.add(AttachmentDatabase.CONTENT_LOCATION); mmsColumnsPresent.add(AttachmentDatabase.CONTENT_LOCATION);
mmsColumnsPresent.add(AttachmentDatabase.DIGEST); mmsColumnsPresent.add(AttachmentDatabase.DIGEST);
mmsColumnsPresent.add(AttachmentDatabase.FAST_PREFLIGHT_ID); mmsColumnsPresent.add(AttachmentDatabase.FAST_PREFLIGHT_ID);
mmsColumnsPresent.add(AttachmentDatabase.VOICE_NOTE);
mmsColumnsPresent.add(AttachmentDatabase.CONTENT_DISPOSITION); mmsColumnsPresent.add(AttachmentDatabase.CONTENT_DISPOSITION);
mmsColumnsPresent.add(AttachmentDatabase.NAME); mmsColumnsPresent.add(AttachmentDatabase.NAME);
mmsColumnsPresent.add(AttachmentDatabase.TRANSFER_STATE); mmsColumnsPresent.add(AttachmentDatabase.TRANSFER_STATE);

View File

@ -103,7 +103,7 @@ public class GroupManager {
if (avatar != null) { if (avatar != null) {
Uri avatarUri = SingleUseBlobProvider.getInstance().createUri(avatar); Uri avatarUri = SingleUseBlobProvider.getInstance().createUri(avatar);
avatarAttachment = new UriAttachment(avatarUri, MediaUtil.IMAGE_PNG, AttachmentDatabase.TRANSFER_PROGRESS_DONE, avatar.length, null); avatarAttachment = new UriAttachment(avatarUri, MediaUtil.IMAGE_PNG, AttachmentDatabase.TRANSFER_PROGRESS_DONE, avatar.length, null, false);
} }
OutgoingGroupMediaMessage outgoingMessage = new OutgoingGroupMediaMessage(groupRecipient, groupContext, avatarAttachment, System.currentTimeMillis(), 0); OutgoingGroupMediaMessage outgoingMessage = new OutgoingGroupMediaMessage(groupRecipient, groupContext, avatarAttachment, System.currentTimeMillis(), 0);

View File

@ -158,7 +158,7 @@ public class AttachmentDownloadJob extends MasterSecretJob implements Injectable
Log.w(TAG, "Downloading attachment with no digest..."); Log.w(TAG, "Downloading attachment with no digest...");
} }
return new SignalServiceAttachmentPointer(id, null, key, relay, Optional.fromNullable(attachment.getDigest()), Optional.fromNullable(attachment.getFileName())); return new SignalServiceAttachmentPointer(id, null, key, relay, Optional.fromNullable(attachment.getDigest()), Optional.fromNullable(attachment.getFileName()), attachment.isVoiceNote());
} catch (InvalidMessageException | IOException e) { } catch (InvalidMessageException | IOException e) {
Log.w(TAG, e); Log.w(TAG, e);
throw new InvalidPartException(e); throw new InvalidPartException(e);

View File

@ -78,7 +78,7 @@ public class AvatarDownloadJob extends MasterSecretJob implements InjectableType
attachment = File.createTempFile("avatar", "tmp", context.getCacheDir()); attachment = File.createTempFile("avatar", "tmp", context.getCacheDir());
attachment.deleteOnExit(); attachment.deleteOnExit();
SignalServiceAttachmentPointer pointer = new SignalServiceAttachmentPointer(avatarId, contentType, key, relay, digest, fileName); SignalServiceAttachmentPointer pointer = new SignalServiceAttachmentPointer(avatarId, contentType, key, relay, digest, fileName, false);
InputStream inputStream = receiver.retrieveAttachment(pointer, attachment, MAX_AVATAR_SIZE); InputStream inputStream = receiver.retrieveAttachment(pointer, attachment, MAX_AVATAR_SIZE);
Bitmap avatar = BitmapUtil.createScaledBitmap(context, new AttachmentModel(attachment, key), 500, 500); Bitmap avatar = BitmapUtil.createScaledBitmap(context, new AttachmentModel(attachment, key), 500, 500);

View File

@ -199,7 +199,7 @@ public class MmsDownloadJob extends MasterSecretJob {
attachments.add(new UriAttachment(uri, Util.toIsoString(part.getContentType()), attachments.add(new UriAttachment(uri, Util.toIsoString(part.getContentType()),
AttachmentDatabase.TRANSFER_PROGRESS_DONE, AttachmentDatabase.TRANSFER_PROGRESS_DONE,
part.getData().length, name)); part.getData().length, name, false));
} }
} }
} }

View File

@ -28,6 +28,7 @@ import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException; import org.whispersystems.signalservice.api.crypto.UntrustedIdentityException;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment; import org.whispersystems.signalservice.api.messages.SignalServiceAttachment;
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream; import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream;
import org.whispersystems.signalservice.api.messages.multidevice.ContactsMessage;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceContact; import org.whispersystems.signalservice.api.messages.multidevice.DeviceContact;
import org.whispersystems.signalservice.api.messages.multidevice.DeviceContactsOutputStream; import org.whispersystems.signalservice.api.messages.multidevice.DeviceContactsOutputStream;
import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage; import org.whispersystems.signalservice.api.messages.multidevice.SignalServiceSyncMessage;
@ -97,7 +98,7 @@ public class MultiDeviceContactUpdateJob extends MasterSecretJob implements Inje
Optional.fromNullable(recipient.getColor().serialize()))); Optional.fromNullable(recipient.getColor().serialize())));
out.close(); out.close();
sendUpdate(messageSender, contactDataFile); sendUpdate(messageSender, contactDataFile, false);
} catch(InvalidNumberException e) { } catch(InvalidNumberException e) {
Log.w(TAG, e); Log.w(TAG, e);
@ -126,7 +127,7 @@ public class MultiDeviceContactUpdateJob extends MasterSecretJob implements Inje
} }
out.close(); out.close();
sendUpdate(messageSender, contactDataFile); sendUpdate(messageSender, contactDataFile, true);
} catch(InvalidNumberException e) { } catch(InvalidNumberException e) {
Log.w(TAG, e); Log.w(TAG, e);
} finally { } finally {
@ -159,7 +160,7 @@ public class MultiDeviceContactUpdateJob extends MasterSecretJob implements Inje
} }
} }
private void sendUpdate(SignalServiceMessageSender messageSender, File contactsFile) private void sendUpdate(SignalServiceMessageSender messageSender, File contactsFile, boolean complete)
throws IOException, UntrustedIdentityException, NetworkException throws IOException, UntrustedIdentityException, NetworkException
{ {
if (contactsFile.length() > 0) { if (contactsFile.length() > 0) {
@ -171,7 +172,7 @@ public class MultiDeviceContactUpdateJob extends MasterSecretJob implements Inje
.build(); .build();
try { try {
messageSender.sendMessage(SignalServiceSyncMessage.forContacts(attachmentStream)); messageSender.sendMessage(SignalServiceSyncMessage.forContacts(new ContactsMessage(attachmentStream, complete)));
} catch (IOException ioe) { } catch (IOException ioe) {
throw new NetworkException(ioe); throw new NetworkException(ioe);
} }

View File

@ -80,6 +80,7 @@ public abstract class PushSendJob extends SendJob {
.withContentType(attachment.getContentType()) .withContentType(attachment.getContentType())
.withLength(attachment.getSize()) .withLength(attachment.getSize())
.withFileName(attachment.getFileName()) .withFileName(attachment.getFileName())
.withVoiceNote(attachment.isVoiceNote())
.withListener(new ProgressListener() { .withListener(new ProgressListener() {
@Override @Override
public void onAttachmentProgress(long total, long progress) { public void onAttachmentProgress(long total, long progress) {

View File

@ -4,6 +4,7 @@ import android.content.Context;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.NetworkInfo; import android.net.NetworkInfo;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.Attachment;
@ -93,7 +94,9 @@ public class MediaNetworkRequirement implements Requirement, ContextDependent {
boolean isAllowed; boolean isAllowed;
if (isNonDocumentType(contentType)) { if (attachment.isVoiceNote() || (MediaUtil.isAudio(attachment) && TextUtils.isEmpty(attachment.getFileName()))) {
isAllowed = isConnectedWifi() || isConnectedMobile();
} else if (isNonDocumentType(contentType)) {
isAllowed = allowedTypes.contains(MediaUtil.getDiscreteMimeType(contentType)); isAllowed = allowedTypes.contains(MediaUtil.getDiscreteMimeType(contentType));
} else { } else {
isAllowed = allowedTypes.contains("documents"); isAllowed = allowedTypes.contains("documents");

View File

@ -465,7 +465,7 @@ public class AttachmentManager {
switch (this) { switch (this) {
case IMAGE: return new ImageSlide(context, uri, dataSize); case IMAGE: return new ImageSlide(context, uri, dataSize);
case GIF: return new GifSlide(context, uri, dataSize); case GIF: return new GifSlide(context, uri, dataSize);
case AUDIO: return new AudioSlide(context, uri, dataSize); case AUDIO: return new AudioSlide(context, uri, dataSize, false);
case VIDEO: return new VideoSlide(context, uri, dataSize); case VIDEO: return new VideoSlide(context, uri, dataSize);
case DOCUMENT: return new DocumentSlide(context, uri, mimeType, dataSize, fileName); case DOCUMENT: return new DocumentSlide(context, uri, mimeType, dataSize, fileName);
default: throw new AssertionError("unrecognized enum"); default: throw new AssertionError("unrecognized enum");

View File

@ -33,12 +33,12 @@ import org.thoughtcrime.securesms.util.ResUtil;
public class AudioSlide extends Slide { public class AudioSlide extends Slide {
public AudioSlide(Context context, Uri uri, long dataSize) { public AudioSlide(Context context, Uri uri, long dataSize, boolean voiceNote) {
super(context, constructAttachmentFromUri(context, uri, MediaUtil.AUDIO_UNSPECIFIED, dataSize, false, null)); super(context, constructAttachmentFromUri(context, uri, MediaUtil.AUDIO_UNSPECIFIED, dataSize, false, null, voiceNote));
} }
public AudioSlide(Context context, Uri uri, long dataSize, String contentType) { public AudioSlide(Context context, Uri uri, long dataSize, String contentType, boolean voiceNote) {
super(context, new UriAttachment(uri, null, contentType, AttachmentDatabase.TRANSFER_PROGRESS_STARTED, dataSize, null, null)); super(context, new UriAttachment(uri, null, contentType, AttachmentDatabase.TRANSFER_PROGRESS_STARTED, dataSize, null, null, voiceNote));
} }
public AudioSlide(Context context, Attachment attachment) { public AudioSlide(Context context, Attachment attachment) {

View File

@ -18,7 +18,7 @@ public class DocumentSlide extends Slide {
@NonNull String contentType, long size, @NonNull String contentType, long size,
@Nullable String fileName) @Nullable String fileName)
{ {
super(context, constructAttachmentFromUri(context, uri, contentType, size, true, fileName)); super(context, constructAttachmentFromUri(context, uri, contentType, size, true, fileName, false));
} }
@Override @Override

View File

@ -14,7 +14,7 @@ public class GifSlide extends ImageSlide {
} }
public GifSlide(Context context, Uri uri, long size) { public GifSlide(Context context, Uri uri, long size) {
super(context, constructAttachmentFromUri(context, uri, MediaUtil.IMAGE_GIF, size, true, null)); super(context, constructAttachmentFromUri(context, uri, MediaUtil.IMAGE_GIF, size, true, null, false));
} }
@Override @Override

View File

@ -35,7 +35,7 @@ public class ImageSlide extends Slide {
} }
public ImageSlide(Context context, Uri uri, long size) { public ImageSlide(Context context, Uri uri, long size) {
super(context, constructAttachmentFromUri(context, uri, MediaUtil.IMAGE_JPEG, size, true, null)); super(context, constructAttachmentFromUri(context, uri, MediaUtil.IMAGE_JPEG, size, true, null, false));
} }
@Override @Override

View File

@ -133,12 +133,13 @@ public abstract class Slide {
@NonNull String defaultMime, @NonNull String defaultMime,
long size, long size,
boolean hasThumbnail, boolean hasThumbnail,
@Nullable String fileName) @Nullable String fileName,
boolean voiceNote)
{ {
try { try {
Optional<String> resolvedType = Optional.fromNullable(MediaUtil.getMimeType(context, uri)); Optional<String> resolvedType = Optional.fromNullable(MediaUtil.getMimeType(context, uri));
String fastPreflightId = String.valueOf(SecureRandom.getInstance("SHA1PRNG").nextLong()); String fastPreflightId = String.valueOf(SecureRandom.getInstance("SHA1PRNG").nextLong());
return new UriAttachment(uri, hasThumbnail ? uri : null, resolvedType.or(defaultMime), AttachmentDatabase.TRANSFER_PROGRESS_STARTED, size, fileName, fastPreflightId); return new UriAttachment(uri, hasThumbnail ? uri : null, resolvedType.or(defaultMime), AttachmentDatabase.TRANSFER_PROGRESS_STARTED, size, fileName, fastPreflightId, voiceNote);
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
throw new AssertionError(e); throw new AssertionError(e);
} }

View File

@ -30,7 +30,7 @@ import org.thoughtcrime.securesms.util.ResUtil;
public class VideoSlide extends Slide { public class VideoSlide extends Slide {
public VideoSlide(Context context, Uri uri, long dataSize) { public VideoSlide(Context context, Uri uri, long dataSize) {
super(context, constructAttachmentFromUri(context, uri, MediaUtil.VIDEO_UNSPECIFIED, dataSize, MediaUtil.hasVideoThumbnail(uri), null)); super(context, constructAttachmentFromUri(context, uri, MediaUtil.VIDEO_UNSPECIFIED, dataSize, MediaUtil.hasVideoThumbnail(uri), null, false));
} }
public VideoSlide(Context context, Attachment attachment) { public VideoSlide(Context context, Attachment attachment) {