fix: share logs dialog blocks to prevent weird context switching blocking the share dialog

This commit is contained in:
0x330a 2023-07-27 15:10:16 +10:00
parent d39cf2754c
commit b8ed7d9394
No known key found for this signature in database
GPG Key ID: 267811D6E6A2698C
1 changed files with 73 additions and 71 deletions

View File

@ -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)) {