From b8ed7d9394d404cadc834060ce135544e51512e9 Mon Sep 17 00:00:00 2001 From: 0x330a <92654767+0x330a@users.noreply.github.com> Date: Thu, 27 Jul 2023 15:10:16 +1000 Subject: [PATCH] fix: share logs dialog blocks to prevent weird context switching blocking the share dialog --- .../securesms/preferences/ShareLogsDialog.kt | 144 +++++++++--------- 1 file changed, 73 insertions(+), 71 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/ShareLogsDialog.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/ShareLogsDialog.kt index e3be429e3..de366dc89 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/ShareLogsDialog.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/ShareLogsDialog.kt @@ -13,12 +13,6 @@ import android.provider.MediaStore import android.webkit.MimeTypeMap import android.widget.Toast import androidx.fragment.app.DialogFragment -import androidx.lifecycle.lifecycleScope -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Dispatchers.Main -import kotlinx.coroutines.Job -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext import network.loki.messenger.BuildConfig import network.loki.messenger.R import org.session.libsignal.utilities.ExternalStorageUtil @@ -35,83 +29,84 @@ import java.util.concurrent.TimeUnit class ShareLogsDialog : DialogFragment() { - private var shareJob: Job? = null - override fun onCreateDialog(savedInstanceState: Bundle?): Dialog = createSessionDialog { title(R.string.dialog_share_logs_title) text(R.string.dialog_share_logs_explanation) - button(R.string.share) { shareLogs() } + button(R.string.share) { + shareLogs() + } cancelButton { dismiss() } } private fun shareLogs() { - shareJob?.cancel() - shareJob = lifecycleScope.launch(Dispatchers.IO) { - val persistentLogger = ApplicationContext.getInstance(context).persistentLogger - try { - val context = requireContext() - val outputUri: Uri = ExternalStorageUtil.getDownloadUri() - val mediaUri = getExternalFile() - if (mediaUri == null) { - // show toast saying media saved - dismiss() - return@launch - } - - val inputStream = persistentLogger.logs.get().byteInputStream() - val updateValues = ContentValues() - if (outputUri.scheme == ContentResolver.SCHEME_FILE) { - FileOutputStream(mediaUri.path).use { outputStream -> - StreamUtil.copy(inputStream, outputStream) - MediaScannerConnection.scanFile(context, arrayOf(mediaUri.path), arrayOf("text/plain"), null) - } - } else { - context.contentResolver.openOutputStream(mediaUri, "w").use { outputStream -> - val total: Long = StreamUtil.copy(inputStream, outputStream) - if (total > 0) { - updateValues.put(MediaStore.MediaColumns.SIZE, total) - } - } - } - if (Build.VERSION.SDK_INT > 28) { - updateValues.put(MediaStore.MediaColumns.IS_PENDING, 0) - } - if (updateValues.size() > 0) { - requireContext().contentResolver.update(mediaUri, updateValues, null, null) - } - - val shareUri = if (mediaUri.scheme == ContentResolver.SCHEME_FILE) { - FileProviderUtil.getUriFor(context, File(mediaUri.path!!)) - } else { - mediaUri - } - - withContext(Main) { - val shareIntent = Intent().apply { - action = Intent.ACTION_SEND - putExtra(Intent.EXTRA_STREAM, shareUri) - type = "text/plain" - addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) - } - startActivity(Intent.createChooser(shareIntent, getString(R.string.share))) - } - - dismiss() - } catch (e: Exception) { - withContext(Main) { - Log.e("Loki", "Error saving logs", e) - Toast.makeText(context,"Error saving logs", Toast.LENGTH_LONG).show() - } + val persistentLogger = ApplicationContext.getInstance(context).persistentLogger + try { + val context = requireContext() + val outputUri: Uri = ExternalStorageUtil.getDownloadUri() + val mediaUri = getExternalFile() + if (mediaUri == null) { + // show toast saying media saved dismiss() + return } + + val inputStream = persistentLogger.logs.get().byteInputStream() + val updateValues = ContentValues() + if (outputUri.scheme == ContentResolver.SCHEME_FILE) { + FileOutputStream(mediaUri.path).use { outputStream -> + StreamUtil.copy(inputStream, outputStream) + MediaScannerConnection.scanFile( + context, + arrayOf(mediaUri.path), + arrayOf("text/plain"), + null + ) + } + } else { + context.contentResolver.openOutputStream(mediaUri, "w").use { outputStream -> + val total: Long = StreamUtil.copy(inputStream, outputStream) + if (total > 0) { + updateValues.put(MediaStore.MediaColumns.SIZE, total) + } + } + } + if (Build.VERSION.SDK_INT > 28) { + updateValues.put(MediaStore.MediaColumns.IS_PENDING, 0) + } + if (updateValues.size() > 0) { + context.contentResolver.update(mediaUri, updateValues, null, null) + } + + val shareUri = if (mediaUri.scheme == ContentResolver.SCHEME_FILE) { + FileProviderUtil.getUriFor(context, File(mediaUri.path!!)) + } else { + mediaUri + } + + val shareIntent = Intent().apply { + action = Intent.ACTION_SEND + putExtra(Intent.EXTRA_STREAM, shareUri) + type = "text/plain" + addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + } + + startActivity(Intent.createChooser(shareIntent, getString(R.string.share))) + + dismiss() + } catch (e: Exception) { + Log.e("Loki", "Error saving logs", e) + Toast.makeText(context, "Error saving logs", Toast.LENGTH_LONG).show() + dismiss() } } @Throws(IOException::class) private fun pathTaken(outputUri: Uri, dataPath: String): Boolean { - requireContext().contentResolver.query(outputUri, arrayOf(MediaStore.MediaColumns.DATA), + requireContext().contentResolver.query( + outputUri, arrayOf(MediaStore.MediaColumns.DATA), MediaStore.MediaColumns.DATA + " = ?", arrayOf(dataPath), - null).use { cursor -> + null + ).use { cursor -> if (cursor == null) { throw IOException("Something is wrong with the filename to save") } @@ -121,7 +116,8 @@ class ShareLogsDialog : DialogFragment() { private fun getExternalFile(): Uri? { val context = requireContext() - val base = "${Build.MANUFACTURER}-${Build.DEVICE}-API${Build.VERSION.SDK_INT}-v${BuildConfig.VERSION_NAME}-${System.currentTimeMillis()}" + val base = + "${Build.MANUFACTURER}-${Build.DEVICE}-API${Build.VERSION.SDK_INT}-v${BuildConfig.VERSION_NAME}-${System.currentTimeMillis()}" val extension = "txt" val fileName = "$base.$extension" val mimeType = MimeTypeMap.getSingleton().getExtensionFromMimeType("text/plain") @@ -129,8 +125,14 @@ class ShareLogsDialog : DialogFragment() { val contentValues = ContentValues() contentValues.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName) contentValues.put(MediaStore.MediaColumns.MIME_TYPE, mimeType) - contentValues.put(MediaStore.MediaColumns.DATE_ADDED, TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())) - contentValues.put(MediaStore.MediaColumns.DATE_MODIFIED, TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis())) + contentValues.put( + MediaStore.MediaColumns.DATE_ADDED, + TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) + ) + contentValues.put( + MediaStore.MediaColumns.DATE_MODIFIED, + TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()) + ) if (Build.VERSION.SDK_INT > 28) { contentValues.put(MediaStore.MediaColumns.IS_PENDING, 1) } else if (Objects.equals(outputUri.scheme, ContentResolver.SCHEME_FILE)) {