Browse Source

Merge branch 'fixDeleteSourceFileWhenCopyFailed' into 'master'

Fix: do not delete the source file when copying failed

See merge request kdanandroid/pdf/pdfreaderreadermodule!23
Wayne Huang 5 years ago
parent
commit
a2fe57ddaa
1 changed files with 57 additions and 24 deletions
  1. 57 24
      src/main/java/com/kdanmobile/reader/copyfile/CopyFileViewModel.kt

+ 57 - 24
src/main/java/com/kdanmobile/reader/copyfile/CopyFileViewModel.kt

@@ -11,6 +11,22 @@ import io.reactivex.android.schedulers.AndroidSchedulers
 import io.reactivex.disposables.Disposable
 import io.reactivex.schedulers.Schedulers
 import java.io.File
+import java.lang.Exception
+
+/**
+ * 1. if info.shouldCopyFile == false,
+ *          just call onCopySuccess() to send Event.Success(destination path)
+ * 2. if source path == destination path,
+ *          just call onCopySuccess() to send Event.Success(destination path)
+ * 3. if the application has no permission,
+ *          send Event.Failed(destination path, FileNotFoundException) and delete the destination file
+ * 4. if an IOException is thrown during copying,
+ *          send Event.Failed(destination path, IOException) and delete the destination file
+ * 5. otherwise, when CopyFileViewModel finishes copying file,
+ *          call onCopySuccess() to send Event.Success(destination path)
+ *
+ * Finally, when CopyFileViewModel::onCleared() is called, delete the destination file if it is not complete copied
+*/
 
 class CopyFileViewModel(applicationContext: Context,
                         private val info: CopyFileInfo,
@@ -28,6 +44,7 @@ class CopyFileViewModel(applicationContext: Context,
     private val mCopyProgressLiveData = MutableLiveData<Int>().apply { value = 0 }
 
     private var copyFileDisposable: Disposable? = null
+    private var srcFilePath: String? = null
     private var dstFilePath: String? = null
     private var hasCompleteCopy = false
 
@@ -38,31 +55,47 @@ class CopyFileViewModel(applicationContext: Context,
     fun copyFile(applicationContext: Context) {
         if (!info.shouldCopyFile) {
             onCopySuccess()
+            return
+        }
+
+        val source = if (!info.filePath.isNullOrEmpty()) {
+            FilePathSource(info.filePath!!)
+        } else if (info.isActionView && null != info.uri) {
+            FileUriSource(applicationContext, info.uri)
         } else {
-            val source = if (!info.filePath.isNullOrEmpty()) {
-                FilePathSource(info.filePath!!)
-            } else if (info.isActionView && null != info.uri) {
-                FileUriSource(applicationContext, info.uri)
-            } else {
-                null
-            }
-            val fullFileSize = Math.max(1, source?.getFileSize() ?: 1)
-            val task = CopyFileTask()
-            task.setCopyMode(CopyFileTask.Mode.CREATE_NEW_FILE)
-            task.setTargetFolder(FileUtil.getKdanPDFReaderFolder())
-            dstFilePath = task.generateUniqueFilePath(source)
-
-            copyFileDisposable = task.copyFile(source)
-                    .subscribeOn(Schedulers.io())
-                    .observeOn(AndroidSchedulers.mainThread())
-                    .subscribe({
-                        val progress = Math.min(100, (it * 100.0 / fullFileSize).toInt())
-                        onCopyProgressUpdate(progress)
-                    }, {
-                        onCopyFailed(it)
-                    }, {
-                        onCopySuccess()
-                    })
+            null
+        }
+        srcFilePath = source?.getFilePath()
+        if (isSrcFileEqualsDstFile()) {
+            onCopySuccess()
+            return
+        }
+
+        val fullFileSize = Math.max(1, source?.getFileSize() ?: 1)
+        val task = CopyFileTask()
+        task.setCopyMode(CopyFileTask.Mode.CREATE_NEW_FILE)
+        task.setTargetFolder(FileUtil.getKdanPDFReaderFolder())
+        dstFilePath = task.generateUniqueFilePath(source)
+
+        copyFileDisposable = task.copyFile(source)
+                .subscribeOn(Schedulers.io())
+                .observeOn(AndroidSchedulers.mainThread())
+                .subscribe({
+                    val progress = Math.min(100, (it * 100.0 / fullFileSize).toInt())
+                    onCopyProgressUpdate(progress)
+                }, {
+                    onCopyFailed(it)
+                }, {
+                    onCopySuccess()
+                })
+    }
+
+    //  check the destination path is the same with the source path or not
+    private fun isSrcFileEqualsDstFile(): Boolean {
+        return try {
+            (!srcFilePath.isNullOrEmpty() && File(srcFilePath).canonicalPath == File(dstFilePath).canonicalPath)
+        } catch (e: Exception) {
+            false
         }
     }