Search in sources :

Example 11 with AttachmentDatabase

use of org.thoughtcrime.securesms.database.AttachmentDatabase in project Signal-Android by WhisperSystems.

the class SendJob method markAttachmentsUploaded.

protected void markAttachmentsUploaded(long messageId, @NonNull OutgoingMediaMessage message) {
    List<Attachment> attachments = new LinkedList<>();
    attachments.addAll(message.getAttachments());
    attachments.addAll(Stream.of(message.getLinkPreviews()).map(lp -> lp.getThumbnail().orNull()).withoutNulls().toList());
    attachments.addAll(Stream.of(message.getSharedContacts()).map(Contact::getAvatarAttachment).withoutNulls().toList());
    if (message.getOutgoingQuote() != null) {
        attachments.addAll(message.getOutgoingQuote().getAttachments());
    }
    AttachmentDatabase database = SignalDatabase.attachments();
    for (Attachment attachment : attachments) {
        database.markAttachmentUploaded(messageId, attachment);
    }
}
Also used : SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) TextSecureExpiredException(org.thoughtcrime.securesms.TextSecureExpiredException) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) Stream(com.annimon.stream.Stream) Contact(org.thoughtcrime.securesms.contactshare.Contact) Util(org.thoughtcrime.securesms.util.Util) NonNull(androidx.annotation.NonNull) AttachmentDatabase(org.thoughtcrime.securesms.database.AttachmentDatabase) Collectors(java.util.stream.Collectors) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) Log(org.signal.core.util.logging.Log) List(java.util.List) Job(org.thoughtcrime.securesms.jobmanager.Job) LinkedList(java.util.LinkedList) BuildConfig(org.thoughtcrime.securesms.BuildConfig) Attachment(org.thoughtcrime.securesms.attachments.Attachment) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) Attachment(org.thoughtcrime.securesms.attachments.Attachment) LinkedList(java.util.LinkedList) AttachmentDatabase(org.thoughtcrime.securesms.database.AttachmentDatabase)

Example 12 with AttachmentDatabase

use of org.thoughtcrime.securesms.database.AttachmentDatabase 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 13 with AttachmentDatabase

use of org.thoughtcrime.securesms.database.AttachmentDatabase 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 14 with AttachmentDatabase

use of org.thoughtcrime.securesms.database.AttachmentDatabase in project Signal-Android by signalapp.

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 15 with AttachmentDatabase

use of org.thoughtcrime.securesms.database.AttachmentDatabase in project Signal-Android by signalapp.

the class SendJob method markAttachmentsUploaded.

protected void markAttachmentsUploaded(long messageId, @NonNull OutgoingMediaMessage message) {
    List<Attachment> attachments = new LinkedList<>();
    attachments.addAll(message.getAttachments());
    attachments.addAll(Stream.of(message.getLinkPreviews()).map(lp -> lp.getThumbnail().orNull()).withoutNulls().toList());
    attachments.addAll(Stream.of(message.getSharedContacts()).map(Contact::getAvatarAttachment).withoutNulls().toList());
    if (message.getOutgoingQuote() != null) {
        attachments.addAll(message.getOutgoingQuote().getAttachments());
    }
    AttachmentDatabase database = SignalDatabase.attachments();
    for (Attachment attachment : attachments) {
        database.markAttachmentUploaded(messageId, attachment);
    }
}
Also used : SignalStore(org.thoughtcrime.securesms.keyvalue.SignalStore) TextSecureExpiredException(org.thoughtcrime.securesms.TextSecureExpiredException) SignalDatabase(org.thoughtcrime.securesms.database.SignalDatabase) Stream(com.annimon.stream.Stream) Contact(org.thoughtcrime.securesms.contactshare.Contact) Util(org.thoughtcrime.securesms.util.Util) NonNull(androidx.annotation.NonNull) AttachmentDatabase(org.thoughtcrime.securesms.database.AttachmentDatabase) Collectors(java.util.stream.Collectors) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) Log(org.signal.core.util.logging.Log) List(java.util.List) Job(org.thoughtcrime.securesms.jobmanager.Job) LinkedList(java.util.LinkedList) BuildConfig(org.thoughtcrime.securesms.BuildConfig) Attachment(org.thoughtcrime.securesms.attachments.Attachment) OutgoingMediaMessage(org.thoughtcrime.securesms.mms.OutgoingMediaMessage) DatabaseAttachment(org.thoughtcrime.securesms.attachments.DatabaseAttachment) Attachment(org.thoughtcrime.securesms.attachments.Attachment) LinkedList(java.util.LinkedList) AttachmentDatabase(org.thoughtcrime.securesms.database.AttachmentDatabase)

Aggregations

AttachmentDatabase (org.thoughtcrime.securesms.database.AttachmentDatabase)35 DatabaseAttachment (org.thoughtcrime.securesms.attachments.DatabaseAttachment)20 Attachment (org.thoughtcrime.securesms.attachments.Attachment)14 MmsException (org.thoughtcrime.securesms.mms.MmsException)13 IOException (java.io.IOException)12 AttachmentId (org.thoughtcrime.securesms.attachments.AttachmentId)10 NonNull (androidx.annotation.NonNull)6 LinkedList (java.util.LinkedList)6 MessageDatabase (org.thoughtcrime.securesms.database.MessageDatabase)6 Job (org.thoughtcrime.securesms.jobmanager.Job)6 UndeliverableMessageException (org.thoughtcrime.securesms.transport.UndeliverableMessageException)6 File (java.io.File)5 PartProgressEvent (org.thoughtcrime.securesms.events.PartProgressEvent)5 Stream (com.annimon.stream.Stream)4 MessageRecord (org.thoughtcrime.securesms.database.model.MessageRecord)4 MediaStream (org.thoughtcrime.securesms.mms.MediaStream)4 SignalServiceAttachmentPointer (org.whispersystems.signalservice.api.messages.SignalServiceAttachmentPointer)4 Nullable (androidx.annotation.Nullable)3 InputStream (java.io.InputStream)3 List (java.util.List)3