Skip to content

Commit

Permalink
Improve backup dialog behaviour
Browse files Browse the repository at this point in the history
  • Loading branch information
cyb3rko committed Feb 17, 2023
1 parent e430282 commit f0755d3
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 91 deletions.
Expand Up @@ -18,24 +18,30 @@ package com.cyb3rko.pincredible.modals

import android.content.Context
import androidx.annotation.StringRes
import androidx.appcompat.app.AlertDialog
import androidx.fragment.app.FragmentActivity
import com.cyb3rko.pincredible.databinding.DialogProgressBinding
import com.google.android.material.dialog.MaterialAlertDialogBuilder

internal object ProgressDialog {
internal class ProgressDialog {
lateinit var dialogReference: AlertDialog
lateinit var binding: DialogProgressBinding
private set

fun show(
context: Context,
@StringRes titleRes: Int,
initialNote: String
): DialogProgressBinding {
val binding = DialogProgressBinding.inflate((context as FragmentActivity).layoutInflater)
) {
binding = DialogProgressBinding.inflate((context as FragmentActivity).layoutInflater)
binding.progressNote.text = initialNote

MaterialAlertDialogBuilder(context)
dialogReference = MaterialAlertDialogBuilder(context)
.setCancelable(false)
.setTitle(titleRes)
.setView(binding.root)
.show()

return binding
.create().apply {
show()
}
}
}
189 changes: 105 additions & 84 deletions app/src/main/kotlin/com/cyb3rko/pincredible/utils/BackupHandler.kt
Expand Up @@ -24,6 +24,7 @@ import androidx.activity.result.ActivityResultLauncher
import com.cyb3rko.pincredible.R
import com.cyb3rko.pincredible.crypto.CryptoManager
import com.cyb3rko.pincredible.data.PinTable
import com.cyb3rko.pincredible.modals.ErrorDialog
import com.cyb3rko.pincredible.modals.PasswordDialog
import com.cyb3rko.pincredible.modals.ProgressDialog
import java.io.File
Expand Down Expand Up @@ -59,56 +60,67 @@ internal object BackupHandler {
}

private fun runExport(context: Context, uri: Uri, hash: String) {
val progressDialog = ProgressDialog.show(
context,
titleRes = R.string.dialog_export_title,
initialNote = context.getString(R.string.dialog_export_state_retrieving, 0)
)
val progressBar = progressDialog.progressBar
val progressNote = progressDialog.progressNote

val fileList = context.fileList()
if (fileList.size > 1) {
val progressStep = 50 / (fileList.size - 1)
val pins = mutableListOf<BackupPinTable>()
context.filesDir.listFiles()?.forEach {
if (it.name.startsWith("p") && it.name != "pins") {
val bytes = CryptoManager.decrypt(it)
val version = bytes[bytes.size - 1]
val pinTable = ObjectSerializer.deserialize(
bytes.copyOfRange(0, bytes.size - 1)
) as PinTable
pins.add(BackupPinTable(pinTable, version, it.name))
progressBar.progress = progressBar.progress + progressStep
progressNote.text = context.getString(
R.string.dialog_export_state_retrieving,
progressBar.progress
)
val progressDialog = ProgressDialog().apply {
show(
context,
titleRes = R.string.dialog_export_title,
initialNote = context.getString(R.string.dialog_export_state_retrieving, 0)
)
}
val progressBar = progressDialog.binding.progressBar
val progressNote = progressDialog.binding.progressNote

try {
val fileList = context.fileList()
if (fileList.size > 1) {
val progressStep = 50 / (fileList.size - 1)
val pins = mutableListOf<BackupPinTable>()
context.filesDir.listFiles()?.forEach {
if (it.name.startsWith("p") && it.name != "pins") {
val bytes = CryptoManager.decrypt(it)
val version = bytes[bytes.size - 1]
val pinTable = ObjectSerializer.deserialize(
bytes.copyOfRange(0, bytes.size - 1)
) as PinTable
pins.add(BackupPinTable(pinTable, version, it.name))
progressBar.progress = progressBar.progress + progressStep
progressNote.text = context.getString(
R.string.dialog_export_state_retrieving,
progressBar.progress
)
}
}
progressBar.progress = 50
progressNote.text = context.getString(
R.string.dialog_export_state_saving,
50
)

val nameFile = File(context.filesDir, "pins")
val names = ObjectSerializer.deserialize(
CryptoManager.decrypt(nameFile)
) as Set<String>

CryptoManager.encrypt(
ObjectSerializer.serialize(
BackupStructure(
pins.toSet(),
names,
CryptoManager.BACKUP_CRYPTO_ITERATION.toByte()
)
),
context.contentResolver.openOutputStream(uri),
hash.take(32)
)

progressBar.progress = 100
progressNote.text = context.getString(R.string.dialog_export_state_finished)
progressDialog.dialogReference.setCancelable(true)
}
progressBar.progress = 50
progressNote.text = context.getString(
R.string.dialog_export_state_saving,
50
)

val nameFile = File(context.filesDir, "pins")
val names = ObjectSerializer.deserialize(CryptoManager.decrypt(nameFile)) as Set<String>

CryptoManager.encrypt(
ObjectSerializer.serialize(
BackupStructure(
pins.toSet(),
names,
CryptoManager.BACKUP_CRYPTO_ITERATION.toByte()
)
),
context.contentResolver.openOutputStream(uri),
hash.take(32)
)

progressBar.progress = 100
progressNote.text = context.getString(R.string.dialog_export_state_finished)
} catch (e: Exception) {
e.printStackTrace()
progressDialog.dialogReference.cancel()
ErrorDialog.show(context, e, R.string.dialog_export_error)
}
}

Expand Down Expand Up @@ -140,46 +152,55 @@ internal object BackupHandler {
uri: Uri,
hash: String
) {
val progressDialog = ProgressDialog.show(
context,
titleRes = R.string.dialog_export_title,
initialNote = context.getString(R.string.dialog_import_state_retrieving, 0)
)
val progressBar = progressDialog.progressBar
val progressNote = progressDialog.progressNote

val bytes = CryptoManager.decrypt(
context.contentResolver.openInputStream(uri),
hash.take(32)
)
progressBar.progress = 25
progressNote.text = context.getString(R.string.dialog_import_state_retrieving, 25)

val backup = ObjectSerializer.deserialize(bytes) as BackupStructure
progressBar.progress = 50
progressNote.text = context.getString(R.string.dialog_import_state_saving, 50)

val nameFile = File(context.filesDir, "pins")
if (nameFile.exists()) {
CryptoManager.appendStrings(nameFile, *backup.names.toTypedArray())
} else {
nameFile.createNewFile()
CryptoManager.encrypt(
ObjectSerializer.serialize(backup.names),
nameFile
val progressDialog = ProgressDialog().apply {
show(
context,
titleRes = R.string.dialog_export_title,
initialNote = context.getString(R.string.dialog_import_state_retrieving, 0)
)
}
val progressStep = 50 / backup.pins.size
backup.pins.forEach {
savePinFile(context, it.fileName, it.pinTable, it.siid)
progressBar.progress = progressBar.progress + progressStep
progressNote.text = context.getString(
R.string.dialog_import_state_saving,
progressBar.progress + progressStep
val progressBar = progressDialog.binding.progressBar
val progressNote = progressDialog.binding.progressNote

try {
val bytes = CryptoManager.decrypt(
context.contentResolver.openInputStream(uri),
hash.take(32)
)
progressBar.progress = 25
progressNote.text = context.getString(R.string.dialog_import_state_retrieving, 25)

val backup = ObjectSerializer.deserialize(bytes) as BackupStructure
progressBar.progress = 50
progressNote.text = context.getString(R.string.dialog_import_state_saving, 50)

val nameFile = File(context.filesDir, "pins")
if (nameFile.exists()) {
CryptoManager.appendStrings(nameFile, *backup.names.toTypedArray())
} else {
nameFile.createNewFile()
CryptoManager.encrypt(
ObjectSerializer.serialize(backup.names),
nameFile
)
}
val progressStep = 50 / backup.pins.size
backup.pins.forEach {
savePinFile(context, it.fileName, it.pinTable, it.siid)
progressBar.progress = progressBar.progress + progressStep
progressNote.text = context.getString(
R.string.dialog_import_state_saving,
progressBar.progress + progressStep
)
}
progressBar.progress = 100
progressNote.text = context.getString(R.string.dialog_import_state_finished)
progressDialog.dialogReference.setCancelable(true)
} catch (e: Exception) {
e.printStackTrace()
progressDialog.dialogReference.cancel()
ErrorDialog.show(context, e, R.string.dialog_import_error)
}
progressBar.progress = 100
progressNote.text = context.getString(R.string.dialog_import_state_finished)
}

@Throws(CryptoManager.EnDecryptionException::class)
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Expand Up @@ -61,10 +61,12 @@
<string name="dialog_export_state_retrieving">%d\%% - Retrieving PINs…</string>
<string name="dialog_export_state_saving">%d\%% - Saving backup file…</string>
<string name="dialog_export_state_finished">100% - PIN export completed</string>
<string name="dialog_export_error">Export error</string>
<string name="dialog_import_title">PIN Import</string>
<string name="dialog_import_state_retrieving">%d\%% - Reading backup file…</string>
<string name="dialog_import_state_saving">%d\%% - Saving restored content…</string>
<string name="dialog_import_state_finished">100% - PIN import completed</string>
<string name="dialog_import_error">Import error</string>
<string name="dialog_image_title">PIN table image</string>
<string name="dialog_image_message">Are you sure?\n\nYou are about to save this unencrypted PIN table to %s.</string>

Expand Down

0 comments on commit f0755d3

Please sign in to comment.