From 674da8827455a2023a117185817f48225b5848b2 Mon Sep 17 00:00:00 2001 From: Anton Chekulaev Date: Tue, 20 Oct 2020 18:58:51 +1100 Subject: [PATCH] Audio extra columns for attachment table. --- .../DatabaseAttachmentAudioExtras.kt | 14 +++++ .../database/AttachmentDatabase.java | 51 ++++++++++++++++++- .../database/helpers/ClassicOpenHelper.java | 9 +++- 3 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 src/org/thoughtcrime/securesms/attachments/DatabaseAttachmentAudioExtras.kt diff --git a/src/org/thoughtcrime/securesms/attachments/DatabaseAttachmentAudioExtras.kt b/src/org/thoughtcrime/securesms/attachments/DatabaseAttachmentAudioExtras.kt new file mode 100644 index 0000000000..48bf768e3b --- /dev/null +++ b/src/org/thoughtcrime/securesms/attachments/DatabaseAttachmentAudioExtras.kt @@ -0,0 +1,14 @@ +package org.thoughtcrime.securesms.attachments + +data class DatabaseAttachmentAudioExtras(val attachmentId: AttachmentId, val visualSamples: ByteArray, val durationMs: Long) { + + override fun equals(other: Any?): Boolean { + return other != null && + other is DatabaseAttachmentAudioExtras && + other.attachmentId == attachmentId + } + + override fun hashCode(): Int { + return attachmentId.hashCode() + } +} \ No newline at end of file diff --git a/src/org/thoughtcrime/securesms/database/AttachmentDatabase.java b/src/org/thoughtcrime/securesms/database/AttachmentDatabase.java index 63bdd4ca70..8e637e0036 100644 --- a/src/org/thoughtcrime/securesms/database/AttachmentDatabase.java +++ b/src/org/thoughtcrime/securesms/database/AttachmentDatabase.java @@ -39,6 +39,7 @@ import org.json.JSONException; import org.thoughtcrime.securesms.attachments.Attachment; import org.thoughtcrime.securesms.attachments.AttachmentId; import org.thoughtcrime.securesms.attachments.DatabaseAttachment; +import org.thoughtcrime.securesms.attachments.DatabaseAttachmentAudioExtras; import org.thoughtcrime.securesms.crypto.AttachmentSecret; import org.thoughtcrime.securesms.crypto.ClassicDecryptingPartInputStream; import org.thoughtcrime.securesms.crypto.ModernDecryptingPartInputStream; @@ -105,6 +106,9 @@ public class AttachmentDatabase extends Database { static final String CAPTION = "caption"; public static final String URL = "url"; public static final String DIRECTORY = "parts"; + // audio/* mime type only related columns. + static final String AUDIO_VISUAL_SAMPLES = "audio_visual_samples"; // Small amount of audio byte samples to visualise the content (e.g. draw waveform) + static final String AUDIO_DURATION = "audio_duration"; // Duration of the audio track in milliseconds. public static final int TRANSFER_PROGRESS_DONE = 0; public static final int TRANSFER_PROGRESS_STARTED = 1; @@ -112,6 +116,7 @@ public class AttachmentDatabase extends Database { public static final int TRANSFER_PROGRESS_FAILED = 3; private static final String PART_ID_WHERE = ROW_ID + " = ? AND " + UNIQUE_ID + " = ?"; + private static final String PART_AUDIO_ONLY_WHERE = CONTENT_TYPE + " LIKE audio/%"; private static final String[] PROJECTION = new String[] {ROW_ID, MMS_ID, CONTENT_TYPE, NAME, CONTENT_DISPOSITION, @@ -121,6 +126,8 @@ public class AttachmentDatabase extends Database { QUOTE, DATA_RANDOM, THUMBNAIL_RANDOM, WIDTH, HEIGHT, CAPTION, STICKER_PACK_ID, STICKER_PACK_KEY, STICKER_ID, URL}; + private static final String[] PROJECTION_AUDIO_EXTRAS = new String[] {AUDIO_VISUAL_SAMPLES, AUDIO_DURATION}; + 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, " + @@ -133,7 +140,8 @@ public class AttachmentDatabase extends Database { 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, " + URL + " TEXT, " + STICKER_PACK_ID + " TEXT DEFAULT NULL, " + - STICKER_PACK_KEY + " DEFAULT NULL, " + STICKER_ID + " INTEGER DEFAULT -1);"; + STICKER_PACK_KEY + " DEFAULT NULL, " + STICKER_ID + " INTEGER DEFAULT -1," + + AUDIO_VISUAL_SAMPLES + " BLOB, " + AUDIO_DURATION + " INTEGER);"; public static final String[] CREATE_INDEXS = { "CREATE INDEX IF NOT EXISTS part_mms_id_index ON " + TABLE_NAME + " (" + MMS_ID + ");", @@ -822,6 +830,47 @@ public class AttachmentDatabase extends Database { } } + /** + * Retrieves the audio extra values associated with the attachment. Only "audio/*" mime type attachments are accepted. + * @return the related audio extras or null in case any of the audio extra columns are empty or the attachment is not an audio. + */ + public @Nullable DatabaseAttachmentAudioExtras getAttachmentAudioExtras(@NonNull AttachmentId attachmentId) { + try (Cursor cursor = databaseHelper.getReadableDatabase() + // We expect all the audio extra values to be present (not null) or reject the whole record. + .query(TABLE_NAME, + PROJECTION_AUDIO_EXTRAS, + PART_ID_WHERE + + " AND " + AUDIO_VISUAL_SAMPLES + " IS NOT NULL" + + " AND " + AUDIO_DURATION + " IS NOT NULL" + + " AND " + PART_AUDIO_ONLY_WHERE, + attachmentId.toStrings(), + null, null, null, "1")) { + + if (cursor == null || !cursor.moveToFirst()) return null; + + byte[] audioSamples = cursor.getBlob(cursor.getColumnIndexOrThrow(AUDIO_VISUAL_SAMPLES)); + long duration = cursor.getLong(cursor.getColumnIndexOrThrow(AUDIO_DURATION)); + + return new DatabaseAttachmentAudioExtras(attachmentId, audioSamples, duration); + } + } + + /** + * Updates audio extra columns for the "audio/*" mime type attachments only. + * @return true if the update operation was successful. + */ + public boolean setAttachmentAudioExtras(@NonNull DatabaseAttachmentAudioExtras extras) { + ContentValues values = new ContentValues(); + values.put(AUDIO_VISUAL_SAMPLES, extras.getVisualSamples()); + values.put(AUDIO_DURATION, extras.getDurationMs()); + + int alteredRows = databaseHelper.getWritableDatabase().update(TABLE_NAME, + values, + PART_ID_WHERE + " AND " + PART_AUDIO_ONLY_WHERE, + extras.getAttachmentId().toStrings()); + + return alteredRows > 0; + } @VisibleForTesting class ThumbnailFetchCallable implements Callable { diff --git a/src/org/thoughtcrime/securesms/database/helpers/ClassicOpenHelper.java b/src/org/thoughtcrime/securesms/database/helpers/ClassicOpenHelper.java index 64123f535f..86cf0872ad 100644 --- a/src/org/thoughtcrime/securesms/database/helpers/ClassicOpenHelper.java +++ b/src/org/thoughtcrime/securesms/database/helpers/ClassicOpenHelper.java @@ -103,7 +103,9 @@ public class ClassicOpenHelper extends SQLiteOpenHelper { private static final int GROUP_RECEIPT_TRACKING = 45; private static final int UNREAD_COUNT_VERSION = 46; private static final int MORE_RECIPIENT_FIELDS = 47; - private static final int DATABASE_VERSION = 47; + private static final int AUDIO_ATTACHMENT_EXTRAS = 48; + + private static final int DATABASE_VERSION = 48; private static final String TAG = ClassicOpenHelper.class.getSimpleName(); @@ -1289,6 +1291,11 @@ public class ClassicOpenHelper extends SQLiteOpenHelper { */ } + if (oldVersion < AUDIO_ATTACHMENT_EXTRAS) { + db.execSQL("ALTER TABLE part ADD COLUMN audio_visual_samples BLOB"); + db.execSQL("ALTER TABLE part ADD COLUMN audio_duration INTEGER"); + } + db.setTransactionSuccessful(); db.endTransaction(); }