Skip to content

Commit 19a7510

Browse files
authored
Merge pull request #22 from OffRange/kotlin-conversion/backup
Kotlin conversion/backup
2 parents 6771f2f + 1be0285 commit 19a7510

File tree

14 files changed

+651
-672
lines changed

14 files changed

+651
-672
lines changed

app/src/main/java/de/davis/passwordmanager/backup/DataBackup.java

Lines changed: 0 additions & 137 deletions
This file was deleted.
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package de.davis.passwordmanager.backup
2+
3+
import android.content.Context
4+
import android.content.DialogInterface
5+
import android.net.Uri
6+
import android.widget.Toast
7+
import androidx.annotation.IntDef
8+
import com.google.android.material.dialog.MaterialAlertDialogBuilder
9+
import de.davis.passwordmanager.R
10+
import de.davis.passwordmanager.dialog.LoadingDialog
11+
import kotlinx.coroutines.Dispatchers
12+
import kotlinx.coroutines.withContext
13+
import java.io.InputStream
14+
import java.io.OutputStream
15+
import javax.crypto.AEADBadTagException
16+
17+
18+
const val TYPE_EXPORT = 0
19+
const val TYPE_IMPORT = 1
20+
21+
@IntDef(TYPE_EXPORT, TYPE_IMPORT)
22+
annotation class Type
23+
24+
abstract class DataBackup(val context: Context) {
25+
26+
private lateinit var loadingDialog: LoadingDialog
27+
28+
@Throws(Exception::class)
29+
internal abstract suspend fun runExport(outputStream: OutputStream): Result
30+
31+
@Throws(Exception::class)
32+
internal abstract suspend fun runImport(inputStream: InputStream): Result
33+
34+
open suspend fun execute(@Type type: Int, uri: Uri, onSyncedHandler: OnSyncedHandler? = null) {
35+
val resolver = context.contentResolver
36+
loadingDialog = LoadingDialog(context).apply {
37+
setTitle(if (type == TYPE_EXPORT) R.string.export else R.string.import_str)
38+
setMessage(R.string.wait_text)
39+
}
40+
val alertDialog = withContext(Dispatchers.Main) { loadingDialog.show() }
41+
42+
try {
43+
withContext(Dispatchers.IO) {
44+
val result: Result = when (type) {
45+
TYPE_EXPORT -> resolver.openOutputStream(uri)?.use { runExport(it) }!!
46+
47+
TYPE_IMPORT -> resolver.openInputStream(uri)?.use { runImport(it) }!!
48+
49+
else -> Result.Error("Unexpected error occurred")
50+
}
51+
52+
handleResult(result, onSyncedHandler)
53+
}
54+
} catch (e: Exception) {
55+
if (e is NullPointerException) return
56+
error(e)
57+
} finally {
58+
alertDialog.dismiss()
59+
}
60+
}
61+
62+
internal suspend fun error(exception: Exception) {
63+
val msg = if (exception is AEADBadTagException)
64+
context.getString(R.string.password_does_not_match)
65+
else
66+
exception.message
67+
68+
withContext(Dispatchers.Main) {
69+
MaterialAlertDialogBuilder(context).apply {
70+
setTitle(R.string.error_title)
71+
setMessage(msg)
72+
setPositiveButton(R.string.ok) { _: DialogInterface?, _: Int -> }
73+
}.show()
74+
}
75+
76+
exception.printStackTrace()
77+
}
78+
79+
private suspend fun handleResult(result: Result, onSyncedHandler: OnSyncedHandler?) =
80+
withContext(Dispatchers.Main) {
81+
if (result is Result.Success) {
82+
Toast.makeText(
83+
context,
84+
if (result.type == TYPE_EXPORT) R.string.backup_stored else R.string.backup_restored,
85+
Toast.LENGTH_LONG
86+
).show()
87+
handleSyncHandler(onSyncedHandler, result)
88+
return@withContext
89+
}
90+
91+
MaterialAlertDialogBuilder(context).apply {
92+
setPositiveButton(R.string.ok) { _: DialogInterface?, _: Int ->
93+
handleSyncHandler(
94+
onSyncedHandler,
95+
result
96+
)
97+
}
98+
99+
if (result is Result.Error) {
100+
setTitle(R.string.error_title)
101+
setMessage(result.message)
102+
} else if (result is Result.Duplicate) {
103+
setTitle(R.string.warning)
104+
setMessage(
105+
context.resources.getQuantityString(
106+
R.plurals.item_existed,
107+
result.count,
108+
result.count
109+
)
110+
)
111+
}
112+
}.show()
113+
}
114+
115+
private fun handleSyncHandler(onSyncedHandler: OnSyncedHandler?, result: Result) {
116+
onSyncedHandler?.onSynced(result)
117+
}
118+
119+
internal suspend fun notifyUpdate(current: Int, max: Int) {
120+
withContext(Dispatchers.Main) {
121+
loadingDialog.updateProgress(current, max)
122+
}
123+
}
124+
125+
interface OnSyncedHandler {
126+
fun onSynced(result: Result?)
127+
}
128+
}

app/src/main/java/de/davis/passwordmanager/backup/Result.java

Lines changed: 0 additions & 46 deletions
This file was deleted.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package de.davis.passwordmanager.backup
2+
3+
sealed class Result {
4+
open class Success(@field:Type val type: Int) : Result()
5+
class Error(val message: String) : Result()
6+
class Duplicate(val count: Int) : Result()
7+
}

app/src/main/java/de/davis/passwordmanager/backup/SecureDataBackup.java

Lines changed: 0 additions & 70 deletions
This file was deleted.

0 commit comments

Comments
 (0)