@@ -19,6 +19,7 @@ import org.cryptomator.domain.exception.FatalBackendException
1919import org.cryptomator.domain.exception.NoDirFileException
2020import org.cryptomator.domain.exception.NoSuchCloudFileException
2121import org.cryptomator.domain.exception.SymLinkException
22+ import org.cryptomator.domain.usecases.CalculateFileHashUseCase
2223import org.cryptomator.domain.usecases.CloudFolderRecursiveListing
2324import org.cryptomator.domain.usecases.CloudNodeRecursiveListing
2425import org.cryptomator.domain.usecases.CopyDataUseCase
@@ -86,8 +87,6 @@ import org.cryptomator.util.file.MimeTypes
8687import java.io.FileInputStream
8788import java.io.FileNotFoundException
8889import java.io.Serializable
89- import java.security.DigestInputStream
90- import java.security.MessageDigest
9190import java.util.function.Supplier
9291import javax.inject.Inject
9392import kotlin.reflect.KClass
@@ -111,6 +110,7 @@ class BrowseFilesPresenter @Inject constructor( //
111110 private val moveFoldersUseCase : MoveFoldersUseCase , //
112111 private val getCloudListRecursiveUseCase : GetCloudListRecursiveUseCase , //
113112 private val getDecryptedCloudForVaultUseCase : GetDecryptedCloudForVaultUseCase , //
113+ private val calculateFileHashUseCase : CalculateFileHashUseCase , //
114114 private val contentResolverUtil : ContentResolverUtil , //
115115 private val addExistingVaultWorkflow : AddExistingVaultWorkflow , //
116116 private val createNewVaultWorkflow : CreateNewVaultWorkflow , //
@@ -541,16 +541,27 @@ class BrowseFilesPresenter @Inject constructor( //
541541 }
542542 openedCloudFile = cloudFile
543543 uriToOpenedFile?.let {
544- openedCloudFileMd5 = calculateDigestFromUri(it)
545- viewFileIntent.setDataAndType(it, mimeTypes.fromFilename(cloudFile.name)?.toString())
546- viewFileIntent.addFlags(Intent .FLAG_GRANT_READ_URI_PERMISSION or Intent .FLAG_GRANT_WRITE_URI_PERMISSION )
547- if (sharedPreferencesHandler.keepUnlockedWhileEditing()) {
548- openWritableFileNotification = OpenWritableFileNotification (context(), it)
549- openWritableFileNotification?.show()
550- val cryptomatorApp = activity().application as CryptomatorApp
551- cryptomatorApp.suspendLock()
552- }
553- requestActivityResult(ActivityResultCallbacks .openFileFinished(openFileType), viewFileIntent)
544+ view?.showProgress(ProgressModel .GENERIC )
545+ calculateFileHashUseCase //
546+ .withUri(it) //
547+ .run (object : DefaultResultHandler <ByteArray >() {
548+ override fun onSuccess (hash : ByteArray ) {
549+ openedCloudFileMd5 = hash
550+ viewFileIntent.setDataAndType(it, mimeTypes.fromFilename(cloudFile.name)?.toString())
551+ viewFileIntent.addFlags(Intent .FLAG_GRANT_READ_URI_PERMISSION or Intent .FLAG_GRANT_WRITE_URI_PERMISSION )
552+ if (sharedPreferencesHandler.keepUnlockedWhileEditing()) {
553+ openWritableFileNotification = OpenWritableFileNotification (context(), it)
554+ openWritableFileNotification?.show()
555+ val cryptomatorApp = activity().application as CryptomatorApp
556+ cryptomatorApp.suspendLock()
557+ }
558+ requestActivityResult(ActivityResultCallbacks .openFileFinished(openFileType), viewFileIntent)
559+ }
560+
561+ override fun onFinished () {
562+ view?.showProgress(ProgressModel .COMPLETED )
563+ }
564+ })
554565 }
555566 }
556567
@@ -585,21 +596,34 @@ class BrowseFilesPresenter @Inject constructor( //
585596 context().revokeUriPermission(uriToOpenedFile, Intent .FLAG_GRANT_WRITE_URI_PERMISSION or Intent .FLAG_GRANT_READ_URI_PERMISSION )
586597
587598 uriToOpenedFile?.let {
588- try {
589- calculateDigestFromUri(it)?.let { hashAfterEdit ->
590- openedCloudFileMd5?.let { hashBeforeEdit ->
591- if (hashAfterEdit.contentEquals(hashBeforeEdit)) {
592- Timber .tag(" BrowseFilesPresenter" ).i(" Opened app finished, file not changed" )
593- deleteFileIfMicrosoftWorkaround(openFileType, uriToOpenedFile)
599+ view?.showProgress(ProgressModel .GENERIC )
600+ calculateFileHashUseCase //
601+ .withUri(it) //
602+ .run (object : DefaultResultHandler <ByteArray >() {
603+ override fun onSuccess (hashAfterEdit : ByteArray ) {
604+ openedCloudFileMd5?.let { hashBeforeEdit ->
605+ if (hashAfterEdit.contentEquals(hashBeforeEdit)) {
606+ Timber .tag(" BrowseFilesPresenter" ).i(" Opened app finished, file not changed" )
607+ deleteFileIfMicrosoftWorkaround(openFileType, uriToOpenedFile)
608+ } else {
609+ uploadChangedFile(openFileType)
610+ }
611+ } ? : deleteFileIfMicrosoftWorkaround(openFileType, uriToOpenedFile)
612+ }
613+
614+ override fun onFinished () {
615+ view?.showProgress(ProgressModel .COMPLETED )
616+ }
617+
618+ override fun onError (e : Throwable ) {
619+ if (e is FileNotFoundException ) {
620+ Timber .tag(" BrowseFilesPresenter" ).e(e, " Failed to read back changes, file isn't present anymore" )
621+ Toast .makeText(context(), R .string.error_file_not_found_after_opening_using_3party, Toast .LENGTH_LONG ).show()
594622 } else {
595- uploadChangedFile(openFileType )
623+ super .onError(e )
596624 }
597- } ? : deleteFileIfMicrosoftWorkaround(openFileType, uriToOpenedFile)
598- }
599- } catch (e: FileNotFoundException ) {
600- Timber .tag(" BrowseFilesPresenter" ).e(e, " Failed to read back changes, file isn't present anymore" )
601- Toast .makeText(context(), R .string.error_file_not_found_after_opening_using_3party, Toast .LENGTH_LONG ).show()
602- }
625+ }
626+ })
603627 }
604628 }
605629
@@ -651,18 +675,6 @@ class BrowseFilesPresenter @Inject constructor( //
651675 openWritableFileNotification?.hide() ? : OpenWritableFileNotification (context(), Uri .EMPTY ).hide()
652676 }
653677
654- @Throws(FileNotFoundException ::class )
655- private fun calculateDigestFromUri (uri : Uri ): ByteArray? {
656- val digest = MessageDigest .getInstance(" MD5" )
657- DigestInputStream (context().contentResolver.openInputStream(uri), digest).use { dis ->
658- val buffer = ByteArray (4096 )
659- // Read all bytes:
660- while (dis.read(buffer) > - 1 ) {
661- }
662- }
663- return digest.digest()
664- }
665-
666678 private val previewCloudFileNodes: ArrayList <CloudFileModel >
667679 get() {
668680 val previewCloudFiles = ArrayList <CloudFileModel >()
@@ -1322,7 +1334,8 @@ class BrowseFilesPresenter @Inject constructor( //
13221334 copyDataUseCase, //
13231335 moveFilesUseCase, //
13241336 moveFoldersUseCase, //
1325- getDecryptedCloudForVaultUseCase
1337+ getDecryptedCloudForVaultUseCase, //
1338+ calculateFileHashUseCase
13261339 )
13271340 this .authenticationExceptionHandler = authenticationExceptionHandler
13281341 }
0 commit comments