Search in sources :

Example 31 with DatabaseAttachment

use of org.thoughtcrime.securesms.attachments.DatabaseAttachment in project Signal-Android by WhisperSystems.

the class MediaOverviewPageFragment method handleMediaPreviewClick.

private void handleMediaPreviewClick(@NonNull MediaDatabase.MediaRecord mediaRecord) {
    if (mediaRecord.getAttachment().getUri() == null) {
        return;
    }
    Context context = getContext();
    if (context == null) {
        return;
    }
    DatabaseAttachment attachment = mediaRecord.getAttachment();
    if (MediaUtil.isVideo(attachment) || MediaUtil.isImage(attachment)) {
        Intent intent = new Intent(context, MediaPreviewActivity.class);
        intent.putExtra(MediaPreviewActivity.DATE_EXTRA, mediaRecord.getDate());
        intent.putExtra(MediaPreviewActivity.SIZE_EXTRA, mediaRecord.getAttachment().getSize());
        intent.putExtra(MediaPreviewActivity.THREAD_ID_EXTRA, threadId);
        intent.putExtra(MediaPreviewActivity.LEFT_IS_RECENT_EXTRA, true);
        intent.putExtra(MediaPreviewActivity.HIDE_ALL_MEDIA_EXTRA, true);
        intent.putExtra(MediaPreviewActivity.SHOW_THREAD_EXTRA, threadId == MediaDatabase.ALL_THREADS);
        intent.putExtra(MediaPreviewActivity.SORTING_EXTRA, sorting.ordinal());
        intent.putExtra(MediaPreviewActivity.IS_VIDEO_GIF, attachment.isVideoGif());
        intent.setDataAndType(mediaRecord.getAttachment().getUri(), mediaRecord.getContentType());
        context.startActivity(intent);
    } else {
        if (!MediaUtil.isAudio(attachment)) {
            showFileExternally(context, mediaRecord);
        }
    }
}
Also used : Context(android.content.Context) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) Intent(android.content.Intent)

Example 32 with DatabaseAttachment

use of org.thoughtcrime.securesms.attachments.DatabaseAttachment in project Signal-Android by WhisperSystems.

the class MediaPreviewActivity method intentFromMediaRecord.

@NonNull
public static Intent intentFromMediaRecord(@NonNull Context context, @NonNull MediaRecord mediaRecord, boolean leftIsRecent) {
    DatabaseAttachment attachment = Objects.requireNonNull(mediaRecord.getAttachment());
    Intent intent = new Intent(context, MediaPreviewActivity.class);
    intent.putExtra(MediaPreviewActivity.THREAD_ID_EXTRA, mediaRecord.getThreadId());
    intent.putExtra(MediaPreviewActivity.DATE_EXTRA, mediaRecord.getDate());
    intent.putExtra(MediaPreviewActivity.SIZE_EXTRA, attachment.getSize());
    intent.putExtra(MediaPreviewActivity.CAPTION_EXTRA, attachment.getCaption());
    intent.putExtra(MediaPreviewActivity.LEFT_IS_RECENT_EXTRA, leftIsRecent);
    intent.putExtra(MediaPreviewActivity.IS_VIDEO_GIF, attachment.isVideoGif());
    intent.setDataAndType(attachment.getUri(), mediaRecord.getContentType());
    return intent;
}
Also used : DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) Intent(android.content.Intent) NonNull(androidx.annotation.NonNull)

Example 33 with DatabaseAttachment

use of org.thoughtcrime.securesms.attachments.DatabaseAttachment in project Signal-Android by WhisperSystems.

the class AudioWaveForm method getWaveForm.

@AnyThread
public void getWaveForm(@NonNull Consumer<AudioFileInfo> onSuccess, @NonNull Runnable onFailure) {
    Uri uri = slide.getUri();
    Attachment attachment = slide.asAttachment();
    if (uri == null) {
        Log.w(TAG, "No uri");
        ThreadUtil.runOnMain(onFailure);
        return;
    }
    String cacheKey = uri.toString();
    AudioFileInfo cached = WAVE_FORM_CACHE.get(cacheKey);
    if (cached != null) {
        Log.i(TAG, "Loaded wave form from cache " + cacheKey);
        ThreadUtil.runOnMain(() -> onSuccess.accept(cached));
        return;
    }
    AUDIO_DECODER_EXECUTOR.execute(() -> {
        AudioFileInfo cachedInExecutor = WAVE_FORM_CACHE.get(cacheKey);
        if (cachedInExecutor != null) {
            Log.i(TAG, "Loaded wave form from cache inside executor" + cacheKey);
            ThreadUtil.runOnMain(() -> onSuccess.accept(cachedInExecutor));
            return;
        }
        AudioHash audioHash = attachment.getAudioHash();
        if (audioHash != null) {
            AudioFileInfo audioFileInfo = AudioFileInfo.fromDatabaseProtobuf(audioHash.getAudioWaveForm());
            if (audioFileInfo.waveForm.length == 0) {
                Log.w(TAG, "Recovering from a wave form generation error  " + cacheKey);
                ThreadUtil.runOnMain(onFailure);
                return;
            } else if (audioFileInfo.waveForm.length != BAR_COUNT) {
                Log.w(TAG, "Wave form from database does not match bar count, regenerating " + cacheKey);
            } else {
                WAVE_FORM_CACHE.put(cacheKey, audioFileInfo);
                Log.i(TAG, "Loaded wave form from DB " + cacheKey);
                ThreadUtil.runOnMain(() -> onSuccess.accept(audioFileInfo));
                return;
            }
        }
        if (attachment instanceof DatabaseAttachment) {
            try {
                AttachmentDatabase attachmentDatabase = SignalDatabase.attachments();
                DatabaseAttachment dbAttachment = (DatabaseAttachment) attachment;
                long startTime = System.currentTimeMillis();
                attachmentDatabase.writeAudioHash(dbAttachment.getAttachmentId(), AudioWaveFormData.getDefaultInstance());
                Log.i(TAG, String.format("Starting wave form generation (%s)", cacheKey));
                AudioFileInfo fileInfo = generateWaveForm(uri);
                Log.i(TAG, String.format(Locale.US, "Audio wave form generation time %d ms (%s)", System.currentTimeMillis() - startTime, cacheKey));
                attachmentDatabase.writeAudioHash(dbAttachment.getAttachmentId(), fileInfo.toDatabaseProtobuf());
                WAVE_FORM_CACHE.put(cacheKey, fileInfo);
                ThreadUtil.runOnMain(() -> onSuccess.accept(fileInfo));
            } catch (Throwable e) {
                Log.w(TAG, "Failed to create audio wave form for " + cacheKey, e);
                ThreadUtil.runOnMain(onFailure);
            }
        } else {
            try {
                Log.i(TAG, "Not in database and not cached. Generating wave form on-the-fly.");
                long startTime = System.currentTimeMillis();
                Log.i(TAG, String.format("Starting wave form generation (%s)", cacheKey));
                AudioFileInfo fileInfo = generateWaveForm(uri);
                Log.i(TAG, String.format(Locale.US, "Audio wave form generation time %d ms (%s)", System.currentTimeMillis() - startTime, cacheKey));
                WAVE_FORM_CACHE.put(cacheKey, fileInfo);
                ThreadUtil.runOnMain(() -> onSuccess.accept(fileInfo));
            } catch (IOException e) {
                Log.w(TAG, "Failed to create audio wave form for " + cacheKey, e);
                ThreadUtil.runOnMain(onFailure);
            }
        }
    });
}
Also used : DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) Attachment(org.thoughtcrime.securesms.attachments.Attachment) ByteString(com.google.protobuf.ByteString) IOException(java.io.IOException) Uri(android.net.Uri) AttachmentDatabase(org.thoughtcrime.securesms.database.AttachmentDatabase) AnyThread(androidx.annotation.AnyThread)

Example 34 with DatabaseAttachment

use of org.thoughtcrime.securesms.attachments.DatabaseAttachment in project Signal-Android by WhisperSystems.

the class LegacyMigrationJob method schedulePendingIncomingParts.

private void schedulePendingIncomingParts(Context context) {
    final AttachmentDatabase attachmentDb = SignalDatabase.attachments();
    final MessageDatabase mmsDb = SignalDatabase.mms();
    final List<DatabaseAttachment> pendingAttachments = SignalDatabase.attachments().getPendingAttachments();
    Log.i(TAG, pendingAttachments.size() + " pending parts.");
    for (DatabaseAttachment attachment : pendingAttachments) {
        final Reader reader = MmsDatabase.readerFor(mmsDb.getMessageCursor(attachment.getMmsId()));
        final MessageRecord record = reader.getNext();
        if (attachment.hasData()) {
            Log.i(TAG, "corrected a pending media part " + attachment.getAttachmentId() + "that already had data.");
            attachmentDb.setTransferState(attachment.getMmsId(), attachment.getAttachmentId(), AttachmentDatabase.TRANSFER_PROGRESS_DONE);
        } else if (record != null && !record.isOutgoing() && record.isPush()) {
            Log.i(TAG, "queuing new attachment download job for incoming push part " + attachment.getAttachmentId() + ".");
            ApplicationDependencies.getJobManager().add(new AttachmentDownloadJob(attachment.getMmsId(), attachment.getAttachmentId(), false));
        }
        reader.close();
    }
}
Also used : MessageDatabase(org.thoughtcrime.securesms.database.MessageDatabase) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) AttachmentDownloadJob(org.thoughtcrime.securesms.jobs.AttachmentDownloadJob) Reader(org.thoughtcrime.securesms.database.MmsDatabase.Reader) MessageRecord(org.thoughtcrime.securesms.database.model.MessageRecord) AttachmentDatabase(org.thoughtcrime.securesms.database.AttachmentDatabase)

Example 35 with DatabaseAttachment

use of org.thoughtcrime.securesms.attachments.DatabaseAttachment in project Signal-Android by WhisperSystems.

the class AttachmentDatabase method updateAttachmentData.

@NonNull
public Attachment updateAttachmentData(@NonNull MasterSecret masterSecret, @NonNull Attachment attachment, @NonNull MediaStream mediaStream) throws MmsException {
    SQLiteDatabase database = databaseHelper.getWritableDatabase();
    DatabaseAttachment databaseAttachment = (DatabaseAttachment) attachment;
    File dataFile = getAttachmentDataFile(databaseAttachment.getAttachmentId(), DATA);
    if (dataFile == null) {
        throw new MmsException("No attachment data found!");
    }
    long dataSize = setAttachmentData(masterSecret, dataFile, mediaStream.getStream());
    ContentValues contentValues = new ContentValues();
    contentValues.put(SIZE, dataSize);
    contentValues.put(CONTENT_TYPE, mediaStream.getMimeType());
    database.update(TABLE_NAME, contentValues, PART_ID_WHERE, databaseAttachment.getAttachmentId().toStrings());
    return new DatabaseAttachment(databaseAttachment.getAttachmentId(), databaseAttachment.getMmsId(), databaseAttachment.hasData(), databaseAttachment.hasThumbnail(), mediaStream.getMimeType(), databaseAttachment.getTransferState(), dataSize, databaseAttachment.getLocation(), databaseAttachment.getKey(), databaseAttachment.getRelay(), databaseAttachment.getDigest());
}
Also used : ContentValues(android.content.ContentValues) MmsException(ws.com.google.android.mms.MmsException) SQLiteDatabase(android.database.sqlite.SQLiteDatabase) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) File(java.io.File) NonNull(android.support.annotation.NonNull)

Aggregations

DatabaseAttachment (org.thoughtcrime.securesms.attachments.DatabaseAttachment)51 LinkedList (java.util.LinkedList)15 AttachmentId (org.thoughtcrime.securesms.attachments.AttachmentId)14 Attachment (org.thoughtcrime.securesms.attachments.Attachment)12 MmsException (org.thoughtcrime.securesms.mms.MmsException)11 NonNull (androidx.annotation.NonNull)10 AttachmentDatabase (org.thoughtcrime.securesms.database.AttachmentDatabase)10 ContentValues (android.content.ContentValues)9 OutgoingMediaMessage (org.thoughtcrime.securesms.mms.OutgoingMediaMessage)9 Nullable (androidx.annotation.Nullable)8 IOException (java.io.IOException)8 List (java.util.List)8 Recipient (org.thoughtcrime.securesms.recipients.Recipient)8 Cursor (android.database.Cursor)7 MessageDatabase (org.thoughtcrime.securesms.database.MessageDatabase)6 OutgoingSecureMediaMessage (org.thoughtcrime.securesms.mms.OutgoingSecureMediaMessage)6 Context (android.content.Context)5 HashMap (java.util.HashMap)5 Contact (org.thoughtcrime.securesms.contactshare.Contact)5 InputStream (java.io.InputStream)4