From 9db5f6ddd2f4bb21e8851891807c6e376da9f449 Mon Sep 17 00:00:00 2001 From: Jeffrey Starke Date: Mon, 24 Mar 2025 10:38:07 -0400 Subject: [PATCH] Use AttachmentSaver to save media preview files to device storage. --- .../mediapreview/MediaPreviewV2Fragment.kt | 44 ++++++++----------- 1 file changed, 18 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewV2Fragment.kt b/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewV2Fragment.kt index 227fb66260..881fa6498f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewV2Fragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/mediapreview/MediaPreviewV2Fragment.kt @@ -1,6 +1,5 @@ package org.thoughtcrime.securesms.mediapreview -import android.Manifest import android.annotation.SuppressLint import android.content.ActivityNotFoundException import android.content.Context @@ -25,6 +24,7 @@ import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat import androidx.core.view.isVisible import androidx.fragment.app.viewModels +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearSmoothScroller import androidx.recyclerview.widget.RecyclerView @@ -37,12 +37,13 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers import io.reactivex.rxjava3.kotlin.subscribeBy +import kotlinx.coroutines.launch import org.signal.core.util.concurrent.LifecycleDisposable -import org.signal.core.util.concurrent.SignalExecutors import org.signal.core.util.concurrent.addTo import org.signal.core.util.logging.Log import org.thoughtcrime.securesms.LoggingFragment import org.thoughtcrime.securesms.R +import org.thoughtcrime.securesms.attachments.AttachmentSaver import org.thoughtcrime.securesms.attachments.DatabaseAttachment import org.thoughtcrime.securesms.components.DeleteSyncEducationDialog import org.thoughtcrime.securesms.components.ViewBinderDelegate @@ -61,7 +62,6 @@ import org.thoughtcrime.securesms.mediapreview.mediarail.MediaRailAdapter.ImageL import org.thoughtcrime.securesms.mediasend.Media import org.thoughtcrime.securesms.mediasend.v2.MediaSelectionActivity import org.thoughtcrime.securesms.mms.PartAuthority -import org.thoughtcrime.securesms.permissions.Permissions import org.thoughtcrime.securesms.recipients.Recipient import org.thoughtcrime.securesms.util.ContextUtil import org.thoughtcrime.securesms.util.DateUtils @@ -69,9 +69,8 @@ import org.thoughtcrime.securesms.util.Debouncer import org.thoughtcrime.securesms.util.FullscreenHelper import org.thoughtcrime.securesms.util.MediaUtil import org.thoughtcrime.securesms.util.MessageConstraintsUtil -import org.thoughtcrime.securesms.util.SaveAttachmentTask +import org.thoughtcrime.securesms.util.SaveAttachmentUtil import org.thoughtcrime.securesms.util.SpanUtil -import org.thoughtcrime.securesms.util.StorageUtil import org.thoughtcrime.securesms.util.ViewUtil import org.thoughtcrime.securesms.util.visible import java.util.Locale @@ -559,29 +558,22 @@ class MediaPreviewV2Fragment : } private fun saveToDisk(mediaItem: MediaTable.MediaRecord) { - SaveAttachmentTask.showWarningDialogIfNecessary(requireContext(), 1) { - if (StorageUtil.canWriteToMediaStore()) { - performSaveToDisk(mediaItem) - return@showWarningDialogIfNecessary - } - Permissions.with(this) - .request(Manifest.permission.WRITE_EXTERNAL_STORAGE) - .ifNecessary() - .withPermanentDenialDialog(getString(R.string.MediaPreviewActivity_signal_needs_the_storage_permission_in_order_to_write_to_external_storage_but_it_has_been_permanently_denied)) - .onAnyDenied { Toast.makeText(requireContext(), R.string.MediaPreviewActivity_unable_to_write_to_external_storage_without_permission, Toast.LENGTH_LONG).show() } - .onAllGranted { performSaveToDisk(mediaItem) } - .execute() + val uri = mediaItem.attachment?.uri + val contentType = mediaItem.attachment?.contentType + if (uri == null || contentType == null) { + Log.w(TAG, "Unable to save attachment with null URI or contentType.") + return } - } - @Suppress("DEPRECATION") - fun performSaveToDisk(mediaItem: MediaTable.MediaRecord) { - val saveTask = SaveAttachmentTask(requireContext()) - val saveDate = if (mediaItem.date > 0) mediaItem.date else System.currentTimeMillis() - val attachment = mediaItem.attachment - val uri = attachment?.uri - if (attachment != null && uri != null) { - saveTask.executeOnExecutor(SignalExecutors.BOUNDED_IO, SaveAttachmentTask.Attachment(uri, attachment.contentType, saveDate, null)) + val attachment = SaveAttachmentUtil.SaveAttachment( + uri = uri, + contentType = contentType, + date = if (mediaItem.date > 0) mediaItem.date else System.currentTimeMillis(), + fileName = null + ) + + lifecycleScope.launch { + AttachmentSaver(this@MediaPreviewV2Fragment).saveAttachments(setOf(attachment)) } }