Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 43 additions & 17 deletions app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -973,7 +973,10 @@ class ChatActivity :
return@launch
}

val file = File(context.cacheDir, filename)
val file = FileUtils.resolveSharedAttachmentFile(context.cacheDir, filename)
if (file == null) {
return@launch
}
if (file.exists()) {
if (isCurrentlyPlaying) {
chatViewModel.pauseMediaPlayer(true)
Expand Down Expand Up @@ -1929,7 +1932,10 @@ class ChatActivity :

private fun setUpWaveform(message: ChatMessage, thenPlay: Boolean = true, backgroundPlayAllowed: Boolean = false) {
val filename = message.fileParameters.name
val file = File(context.cacheDir, filename!!)
val file = FileUtils.resolveSharedAttachmentFile(context.cacheDir, filename)
if (file == null) {
return
}
if (file.exists() && message.voiceMessageFloatArray == null) {
message.isDownloadingVoiceMessage = true
chatViewModel.syncVoiceMessageUiState(message)
Expand Down Expand Up @@ -2537,7 +2543,12 @@ class ChatActivity :
if (cursor != null && cursor.moveToFirst()) {
val id = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID))
val fileName = ContactUtils.getDisplayNameFromDeviceContact(context, id) + ".vcf"
val file = File(context.cacheDir, fileName)
val file = FileUtils.resolveSharedAttachmentFile(context.cacheDir, fileName)
if (file == null) {
Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
cursor.close()
return
}
writeContactToVcfFile(cursor, file)

val shareUri = FileProvider.getUriForFile(
Expand Down Expand Up @@ -4039,12 +4050,16 @@ class ChatActivity :
}

fun share(message: ChatMessage) {
val filename = message.fileParameters.name
path = applicationContext.cacheDir.absolutePath + "/" + filename
val sharedFile = FileUtils.resolveSharedAttachmentFile(applicationContext.cacheDir, message.fileParameters.name)
if (sharedFile == null) {
Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
return
}
path = sharedFile.absolutePath
val shareUri = FileProvider.getUriForFile(
this,
BuildConfig.APPLICATION_ID,
File(path)
sharedFile
)

val shareIntent: Intent = Intent().apply {
Expand All @@ -4057,9 +4072,12 @@ class ChatActivity :
}

fun checkIfSharable(message: ChatMessage) {
val filename = message.fileParameters.name
path = applicationContext.cacheDir.absolutePath + "/" + filename
val file = File(context.cacheDir, filename!!)
val file = FileUtils.resolveSharedAttachmentFile(context.cacheDir, message.fileParameters.name)
if (file == null) {
Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
return
}
path = file.absolutePath
if (file.exists()) {
share(message)
} else {
Expand All @@ -4080,9 +4098,12 @@ class ChatActivity :
}

fun checkIfSaveable(message: ChatMessage) {
val filename = message.fileParameters.name
path = applicationContext.cacheDir.absolutePath + "/" + filename
val file = File(context.cacheDir, filename!!)
val file = FileUtils.resolveSharedAttachmentFile(context.cacheDir, message.fileParameters.name)
if (file == null) {
Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
return
}
path = file.absolutePath
if (file.exists()) {
showSaveToStorageWarning(message)
} else {
Expand Down Expand Up @@ -4112,12 +4133,16 @@ class ChatActivity :
var metaData = ""
var objectId = ""
if (message.hasFileAttachment) {
val filename = message.fileParameters.name
path = applicationContext.cacheDir.absolutePath + "/" + filename
val file = FileUtils.resolveSharedAttachmentFile(context.cacheDir, message.fileParameters.name)
if (file == null) {
Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
return@launch
}
path = file.absolutePath
shareUri = FileProvider.getUriForFile(
context,
BuildConfig.APPLICATION_ID,
File(path)
file
)

grantUriPermission(
Expand Down Expand Up @@ -4342,14 +4367,15 @@ class ChatActivity :
Intent(MediaStore.ACTION_VIDEO_CAPTURE).also { takeVideoIntent ->
takeVideoIntent.resolveActivity(packageManager)?.also {
val videoFile: File? = try {
val outputDir = context.cacheDir
val outputDir = FileUtils.getSharedAttachmentsDirectory(context.cacheDir)
?: throw IOException("Could not create shared attachments directory")
val dateFormat = SimpleDateFormat(FILE_DATE_PATTERN, Locale.ROOT)
val date = dateFormat.format(Date())
val videoName = String.format(
context.resources.getString(R.string.nc_video_filename),
date
)
File("$outputDir/$videoName$VIDEO_SUFFIX")
File(outputDir, "$videoName$VIDEO_SUFFIX")
} catch (e: IOException) {
Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
Log.e(TAG, "error while creating video file", e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package com.nextcloud.talk.fullscreenfile

import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.widget.FrameLayout
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.material3.MaterialTheme
Expand All @@ -35,6 +36,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.ui.SwipeToCloseLayout
import com.nextcloud.talk.ui.dialog.SaveToStorageDialogFragment
import com.nextcloud.talk.ui.theme.ViewThemeUtils
import com.nextcloud.talk.utils.FileUtils
import com.nextcloud.talk.utils.Mimetype.IMAGE_PREFIX_GENERIC
import java.io.File
import javax.inject.Inject
Expand All @@ -48,6 +50,7 @@ class FullScreenImageActivity : AppCompatActivity() {
private lateinit var windowInsetsController: WindowInsetsControllerCompat
private lateinit var path: String
private lateinit var fileName: String
private lateinit var imageFile: File
private lateinit var swipeToCloseLayout: SwipeToCloseLayout
private var showFullscreen by mutableStateOf(false)

Expand All @@ -57,7 +60,12 @@ class FullScreenImageActivity : AppCompatActivity() {

fileName = intent.getStringExtra("FILE_NAME").orEmpty()
val isGif = intent.getBooleanExtra("IS_GIF", false)
path = applicationContext.cacheDir.absolutePath + "/" + fileName
imageFile = FileUtils.resolveSharedAttachmentFile(applicationContext.cacheDir, fileName) ?: run {
Log.e(TAG, "Invalid image filename: $fileName")
finish()
return
}
path = imageFile.absolutePath

enableEdgeToEdge(
statusBarStyle = SystemBarStyle.dark(android.graphics.Color.TRANSPARENT),
Expand Down Expand Up @@ -123,7 +131,7 @@ class FullScreenImageActivity : AppCompatActivity() {
}

private fun shareFile() {
val shareUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID, File(path))
val shareUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID, imageFile)
val shareIntent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_STREAM, shareUri)
Expand All @@ -141,4 +149,8 @@ class FullScreenImageActivity : AppCompatActivity() {
private fun showBitmapError() {
Snackbar.make(swipeToCloseLayout, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
}

companion object {
private val TAG = FullScreenImageActivity::class.java.simpleName
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ package com.nextcloud.talk.fullscreenfile

import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.WindowManager
import android.widget.FrameLayout
import androidx.activity.SystemBarStyle
Expand Down Expand Up @@ -41,6 +42,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.ui.SwipeToCloseLayout
import com.nextcloud.talk.ui.dialog.SaveToStorageDialogFragment
import com.nextcloud.talk.ui.theme.ViewThemeUtils
import com.nextcloud.talk.utils.FileUtils
import com.nextcloud.talk.utils.Mimetype.VIDEO_PREFIX_GENERIC
import java.io.File
import javax.inject.Inject
Expand All @@ -53,6 +55,7 @@ class FullScreenMediaActivity : AppCompatActivity() {

private lateinit var path: String
private lateinit var fileName: String
private lateinit var mediaFile: File
private var player: ExoPlayer? by mutableStateOf(null)
private var playWhenReadyState: Boolean = true
private var playBackPosition: Long = 0L
Expand All @@ -64,7 +67,12 @@ class FullScreenMediaActivity : AppCompatActivity() {

fileName = intent.getStringExtra("FILE_NAME").orEmpty()
val isAudioOnly = intent.getBooleanExtra("AUDIO_ONLY", false)
path = applicationContext.cacheDir.absolutePath + "/" + fileName
mediaFile = FileUtils.resolveSharedAttachmentFile(applicationContext.cacheDir, fileName) ?: run {
Log.e(TAG, "Invalid media filename: $fileName")
finish()
return
}
path = mediaFile.absolutePath

enableEdgeToEdge(
statusBarStyle = SystemBarStyle.dark(android.graphics.Color.TRANSPARENT),
Expand Down Expand Up @@ -128,7 +136,7 @@ class FullScreenMediaActivity : AppCompatActivity() {
}

private fun preparePlayer() {
val mediaItem: MediaItem = MediaItem.fromUri(File(path).toUri())
val mediaItem: MediaItem = MediaItem.fromUri(mediaFile.toUri())
player?.let { exoPlayer ->
exoPlayer.setMediaItem(mediaItem)
exoPlayer.playWhenReady = playWhenReadyState
Expand Down Expand Up @@ -160,7 +168,7 @@ class FullScreenMediaActivity : AppCompatActivity() {
}

private fun shareFile() {
val shareUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID, File(path))
val shareUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID, mediaFile)
val shareIntent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_STREAM, shareUri)
Expand All @@ -174,4 +182,8 @@ class FullScreenMediaActivity : AppCompatActivity() {
val saveFragment: DialogFragment = SaveToStorageDialogFragment.newInstance(fileName)
saveFragment.show(supportFragmentManager, SaveToStorageDialogFragment.TAG)
}

companion object {
private val TAG = FullScreenMediaActivity::class.java.simpleName
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ package com.nextcloud.talk.fullscreenfile
import android.content.ComponentName
import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.material3.MaterialTheme
Expand All @@ -25,6 +26,7 @@ import com.nextcloud.talk.components.ColoredStatusBar
import com.nextcloud.talk.ui.dialog.SaveToStorageDialogFragment
import com.nextcloud.talk.ui.theme.ViewThemeUtils
import com.nextcloud.talk.utils.AccountUtils.canWeOpenFilesApp
import com.nextcloud.talk.utils.FileUtils
import com.nextcloud.talk.utils.Mimetype.TEXT_PREFIX_GENERIC
import com.nextcloud.talk.utils.adjustUIForAPILevel35
import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ACCOUNT
Expand All @@ -37,6 +39,7 @@ class FullScreenTextViewerActivity : AppCompatActivity() {

@Inject
lateinit var viewThemeUtils: ViewThemeUtils
private lateinit var textFile: File

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Expand All @@ -48,8 +51,12 @@ class FullScreenTextViewerActivity : AppCompatActivity() {
val link = intent.getStringExtra("LINK")
val username = intent.getStringExtra("USERNAME").orEmpty()
val baseUrl = intent.getStringExtra("BASE_URL").orEmpty()
val path = applicationContext.cacheDir.absolutePath + "/" + fileName
val text = readFile(path)
textFile = FileUtils.resolveSharedAttachmentFile(applicationContext.cacheDir, fileName) ?: run {
Log.e(TAG, "Invalid text filename: $fileName")
finish()
return
}
val text = readFile(textFile)

adjustUIForAPILevel35()

Expand All @@ -62,7 +69,7 @@ class FullScreenTextViewerActivity : AppCompatActivity() {
text = text,
isMarkdown = isMarkdown,
actions = FullScreenTextActions(
onShare = { shareFile(path) },
onShare = { shareFile() },
onSave = { showSaveDialog(fileName) },
onOpenInFilesApp = if (fileId.isNotEmpty()) {
{ openInFilesApp(link, fileId, username, baseUrl) }
Expand Down Expand Up @@ -94,8 +101,8 @@ class FullScreenTextViewerActivity : AppCompatActivity() {
}
}

private fun shareFile(path: String) {
val shareUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID, File(path))
private fun shareFile() {
val shareUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID, textFile)
val shareIntent = Intent().apply {
action = Intent.ACTION_SEND
putExtra(Intent.EXTRA_STREAM, shareUri)
Expand All @@ -110,5 +117,9 @@ class FullScreenTextViewerActivity : AppCompatActivity() {
saveFragment.show(supportFragmentManager, SaveToStorageDialogFragment.TAG)
}

private fun readFile(fileName: String) = File(fileName).inputStream().readBytes().toString(Charsets.UTF_8)
private fun readFile(file: File) = file.inputStream().readBytes().toString(Charsets.UTF_8)

companion object {
private val TAG = FullScreenTextViewerActivity::class.java.simpleName
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import com.nextcloud.talk.application.NextcloudTalkApplication
import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.users.UserManager
import com.nextcloud.talk.utils.ApiUtils
import com.nextcloud.talk.utils.FileUtils
import com.nextcloud.talk.utils.database.user.CurrentUserProviderOld
import com.nextcloud.talk.utils.preferences.AppPreferences
import okhttp3.ResponseBody
Expand Down Expand Up @@ -88,15 +89,21 @@ class DownloadFileToCacheWorker(val context: Context, workerParameters: WorkerPa
}

private fun executeDownload(body: ResponseBody?, fileName: String): Result {
if (body == null) {
Log.e(TAG, "Response body when downloading $fileName is null!")
val targetFile = FileUtils.resolveSharedAttachmentFile(context.cacheDir, fileName)
if (body == null || targetFile == null) {
if (body == null) {
Log.e(TAG, "Response body when downloading $fileName is null!")
}
if (targetFile == null) {
Log.e(TAG, "Refused to download file with unsafe name: $fileName")
}
return Result.failure()
}

var count: Int
val data = ByteArray(BYTE_UNIT_DIVIDER * DATA_BYTES)
val bis: InputStream = BufferedInputStream(body.byteStream(), BYTE_UNIT_DIVIDER * DOWNLOAD_STREAM_SIZE)
val outputFile = File(context.cacheDir, fileName + "_")
val outputFile = File(targetFile.parentFile, targetFile.name + "_")
val output: OutputStream = FileOutputStream(outputFile)
var total: Long = 0
val startTime = System.currentTimeMillis()
Expand All @@ -122,20 +129,16 @@ class DownloadFileToCacheWorker(val context: Context, workerParameters: WorkerPa
output.close()
bis.close()

return onDownloadComplete(fileName)
return onDownloadComplete(outputFile, targetFile)
}

private fun onDownloadComplete(fileName: String): Result {
val tempFile = File(context.cacheDir, fileName + "_")
val targetFile = File(context.cacheDir, fileName)

return if (tempFile.renameTo(targetFile)) {
private fun onDownloadComplete(tempFile: File, targetFile: File): Result =
if (tempFile.renameTo(targetFile)) {
setProgressAsync(Data.Builder().putBoolean(SUCCESS, true).build())
Result.success()
} else {
Result.failure()
}
}

companion object {
const val TAG = "DownloadFileToCache"
Expand Down
Loading
Loading