mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Better Action runnable implementation
This commit is contained in:
@@ -430,7 +430,7 @@ class EntryActivity : LockingHideActivity() {
|
||||
TODO Slowdown when add entry as result
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra(EntryEditActivity.ADD_OR_UPDATE_ENTRY_KEY, mEntry);
|
||||
setResult(EntryEditActivity.UPDATE_ENTRY_RESULT_CODE, intent);
|
||||
onFinish(EntryEditActivity.UPDATE_ENTRY_RESULT_CODE, intent);
|
||||
*/
|
||||
super.finish()
|
||||
}
|
||||
|
||||
@@ -175,6 +175,23 @@ class PasswordActivity : StylishActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the password in view in all cases
|
||||
removePassword()
|
||||
|
||||
if (result.isSuccess) {
|
||||
launchGroupActivity()
|
||||
} else {
|
||||
var resultError = ""
|
||||
val resultException = result.exception
|
||||
val resultMessage = result.message
|
||||
|
||||
if (resultException != null) {
|
||||
resultError = resultException.getLocalizedMessage(resources)
|
||||
|
||||
// Relaunch loading if we need to fix UUID
|
||||
if (resultException is LoadDatabaseDuplicateUuidException) {
|
||||
showLoadDatabaseDuplicateUuidMessage {
|
||||
|
||||
var databaseUri: Uri? = null
|
||||
var masterPassword: String? = null
|
||||
var keyFileUri: Uri? = null
|
||||
@@ -190,20 +207,6 @@ class PasswordActivity : StylishActivity() {
|
||||
}
|
||||
|
||||
databaseUri?.let { databaseFileUri ->
|
||||
// Remove the password in view in all cases
|
||||
removePassword()
|
||||
|
||||
if (result.isSuccess) {
|
||||
launchGroupActivity()
|
||||
} else {
|
||||
var resultError = ""
|
||||
val resultException = result.exception
|
||||
val resultMessage = result.message
|
||||
|
||||
if (resultException != null) {
|
||||
resultError = resultException.getLocalizedMessage(resources)
|
||||
if (resultException is LoadDatabaseDuplicateUuidException)
|
||||
showLoadDatabaseDuplicateUuidMessage {
|
||||
showProgressDialogAndLoadDatabase(
|
||||
databaseFileUri,
|
||||
masterPassword,
|
||||
@@ -213,13 +216,14 @@ class PasswordActivity : StylishActivity() {
|
||||
true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Show error message
|
||||
if (resultMessage != null && resultMessage.isNotEmpty()) {
|
||||
resultError = "$resultError $resultMessage"
|
||||
}
|
||||
|
||||
Log.e(TAG, resultError, resultException)
|
||||
|
||||
Snackbar.make(activity_password_coordinator_layout,
|
||||
resultError,
|
||||
Snackbar.LENGTH_LONG).asError().show()
|
||||
@@ -228,7 +232,6 @@ class PasswordActivity : StylishActivity() {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun launchGroupActivity() {
|
||||
EntrySelectionHelper.doEntrySelectionAction(intent,
|
||||
|
||||
@@ -22,22 +22,20 @@ package com.kunzisoft.keepass.database.action
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.tasks.ActionRunnable
|
||||
import com.kunzisoft.keepass.utils.UriUtil
|
||||
|
||||
open class AssignPasswordInDatabaseRunnable @JvmOverloads constructor(
|
||||
open class AssignPasswordInDatabaseRunnable (
|
||||
context: Context,
|
||||
database: Database,
|
||||
withMasterPassword: Boolean,
|
||||
masterPassword: String?,
|
||||
withKeyFile: Boolean,
|
||||
keyFile: Uri?,
|
||||
save: Boolean,
|
||||
actionRunnable: ActionRunnable? = null)
|
||||
: SaveDatabaseRunnable(context, database, save, actionRunnable) {
|
||||
save: Boolean)
|
||||
: SaveDatabaseRunnable(context, database, save) {
|
||||
|
||||
private var mMasterPassword: String? = null
|
||||
private var mKeyFile: Uri? = null
|
||||
protected var mKeyFile: Uri? = null
|
||||
|
||||
private var mBackupKey: ByteArray? = null
|
||||
|
||||
@@ -48,7 +46,7 @@ open class AssignPasswordInDatabaseRunnable @JvmOverloads constructor(
|
||||
this.mKeyFile = keyFile
|
||||
}
|
||||
|
||||
override fun run() {
|
||||
override fun onStartRun() {
|
||||
// Set key
|
||||
try {
|
||||
// TODO move master key methods
|
||||
@@ -57,17 +55,17 @@ open class AssignPasswordInDatabaseRunnable @JvmOverloads constructor(
|
||||
|
||||
val uriInputStream = UriUtil.getUriInputStream(context.contentResolver, mKeyFile)
|
||||
database.retrieveMasterKey(mMasterPassword, uriInputStream)
|
||||
|
||||
// To save the database
|
||||
super.run()
|
||||
finishRun(true)
|
||||
} catch (e: Exception) {
|
||||
erase(mBackupKey)
|
||||
finishRun(false, e.message)
|
||||
}
|
||||
setError(e.message)
|
||||
}
|
||||
|
||||
override fun onFinishRun(result: Result) {
|
||||
super.onStartRun()
|
||||
}
|
||||
|
||||
override fun onFinishRun() {
|
||||
super.onFinishRun()
|
||||
|
||||
if (!result.isSuccess) {
|
||||
// Erase the current master key
|
||||
erase(database.masterKey)
|
||||
@@ -75,8 +73,6 @@ open class AssignPasswordInDatabaseRunnable @JvmOverloads constructor(
|
||||
database.masterKey = it
|
||||
}
|
||||
}
|
||||
|
||||
super.onFinishRun(result)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,8 +21,9 @@ package com.kunzisoft.keepass.database.action
|
||||
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
|
||||
import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.tasks.ActionRunnable
|
||||
|
||||
class CreateDatabaseRunnable(context: Context,
|
||||
private val mDatabaseUri: Uri,
|
||||
@@ -31,28 +32,34 @@ class CreateDatabaseRunnable(context: Context,
|
||||
masterPassword: String?,
|
||||
withKeyFile: Boolean,
|
||||
keyFile: Uri?,
|
||||
save: Boolean,
|
||||
actionRunnable: ActionRunnable? = null)
|
||||
: AssignPasswordInDatabaseRunnable(context, mDatabase, withMasterPassword, masterPassword, withKeyFile, keyFile, save, actionRunnable) {
|
||||
save: Boolean)
|
||||
: AssignPasswordInDatabaseRunnable(context, mDatabase, withMasterPassword, masterPassword, withKeyFile, keyFile, save) {
|
||||
|
||||
override fun run() {
|
||||
override fun onStartRun() {
|
||||
try {
|
||||
// Create new database record
|
||||
mDatabase.apply {
|
||||
createData(mDatabaseUri)
|
||||
// Set Database state
|
||||
loaded = true
|
||||
// Commit changes
|
||||
super.run()
|
||||
}
|
||||
|
||||
finishRun(true)
|
||||
} catch (e: Exception) {
|
||||
|
||||
mDatabase.closeAndClear()
|
||||
finishRun(false, e.message)
|
||||
}
|
||||
setError(e.message)
|
||||
}
|
||||
|
||||
override fun onFinishRun(result: Result) {}
|
||||
super.onStartRun()
|
||||
}
|
||||
|
||||
override fun onFinishRun() {
|
||||
super.onFinishRun()
|
||||
|
||||
if (result.isSuccess) {
|
||||
// Add database to recent files
|
||||
FileDatabaseHistoryAction.getInstance(context.applicationContext)
|
||||
.addOrUpdateDatabaseUri(mDatabaseUri, mKeyFile)
|
||||
} else {
|
||||
Log.e("CreateDatabaseRunnable", "Unable to create the database")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ import com.kunzisoft.keepass.app.database.CipherDatabaseAction
|
||||
import com.kunzisoft.keepass.app.database.CipherDatabaseEntity
|
||||
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
|
||||
import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.database.exception.LoadDatabaseDuplicateUuidException
|
||||
import com.kunzisoft.keepass.database.exception.LoadDatabaseException
|
||||
import com.kunzisoft.keepass.notifications.DatabaseOpenNotificationService
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
@@ -42,16 +43,18 @@ class LoadDatabaseRunnable(private val context: Context,
|
||||
private val mOmitBackup: Boolean,
|
||||
private val mFixDuplicateUUID: Boolean,
|
||||
private val progressTaskUpdater: ProgressTaskUpdater?,
|
||||
private val mOnFinish: ((Result) -> Unit)?)
|
||||
: ActionRunnable(null, executeNestedActionIfResultFalse = true) {
|
||||
private val mDuplicateUuidAction: ((Result) -> Unit)?)
|
||||
: ActionRunnable() {
|
||||
|
||||
private val cacheDirectory = context.applicationContext.filesDir
|
||||
|
||||
override fun run() {
|
||||
try {
|
||||
override fun onStartRun() {
|
||||
// Clear before we load
|
||||
mDatabase.closeAndClear(cacheDirectory)
|
||||
}
|
||||
|
||||
override fun onActionRun() {
|
||||
try {
|
||||
mDatabase.loadData(mUri, mPass, mKey,
|
||||
mReadonly,
|
||||
context.contentResolver,
|
||||
@@ -59,7 +62,18 @@ class LoadDatabaseRunnable(private val context: Context,
|
||||
mOmitBackup,
|
||||
mFixDuplicateUUID,
|
||||
progressTaskUpdater)
|
||||
}
|
||||
catch (e: LoadDatabaseDuplicateUuidException) {
|
||||
mDuplicateUuidAction?.invoke(result)
|
||||
setError(e)
|
||||
}
|
||||
catch (e: LoadDatabaseException) {
|
||||
setError(e)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFinishRun() {
|
||||
if (result.isSuccess) {
|
||||
// Save keyFile in app database
|
||||
val rememberKeyFile = PreferencesUtil.rememberKeyFiles(context)
|
||||
if (rememberKeyFile) {
|
||||
@@ -71,28 +85,15 @@ class LoadDatabaseRunnable(private val context: Context,
|
||||
.addOrUpdateDatabaseUri(mUri, keyUri)
|
||||
}
|
||||
|
||||
mOnFinish?.invoke(result)
|
||||
|
||||
// Register the biometric
|
||||
mCipherEntity?.let { cipherDatabaseEntity ->
|
||||
CipherDatabaseAction.getInstance(context)
|
||||
.addOrUpdateCipherDatabase(cipherDatabaseEntity) {
|
||||
finishRun(true)
|
||||
}
|
||||
} ?: run {
|
||||
finishRun(true)
|
||||
}
|
||||
}
|
||||
catch (e: LoadDatabaseException) {
|
||||
finishRun(false, e)
|
||||
.addOrUpdateCipherDatabase(cipherDatabaseEntity) // return value not called
|
||||
}
|
||||
|
||||
// Start the opening notification
|
||||
context.startService(Intent(context, DatabaseOpenNotificationService::class.java))
|
||||
}
|
||||
|
||||
override fun onFinishRun(result: Result) {
|
||||
if (!result.isSuccess) {
|
||||
} else {
|
||||
mDatabase.closeAndClear(cacheDirectory)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,39 +25,29 @@ import com.kunzisoft.keepass.database.exception.DatabaseOutputException
|
||||
import com.kunzisoft.keepass.tasks.ActionRunnable
|
||||
import java.io.IOException
|
||||
|
||||
abstract class SaveDatabaseRunnable(protected var context: Context,
|
||||
open class SaveDatabaseRunnable(protected var context: Context,
|
||||
protected var database: Database,
|
||||
protected var saveDatabase: Boolean,
|
||||
nestedAction: ActionRunnable? = null)
|
||||
: ActionRunnable(nestedAction) {
|
||||
private var saveDatabase: Boolean)
|
||||
: ActionRunnable() {
|
||||
|
||||
override fun run() {
|
||||
if (saveDatabase) {
|
||||
var mAfterSaveDatabase: ((Result) -> Unit)? = null
|
||||
|
||||
override fun onStartRun() {}
|
||||
|
||||
override fun onActionRun() {
|
||||
if (saveDatabase && result.isSuccess) {
|
||||
try {
|
||||
database.saveData(context.contentResolver)
|
||||
} catch (e: IOException) {
|
||||
finishRun(false, e.message)
|
||||
setError(e.message)
|
||||
} catch (e: DatabaseOutputException) {
|
||||
finishRun(false, e.message)
|
||||
setError(e.message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Need to call super.run() in child class
|
||||
}
|
||||
|
||||
override fun onFinishRun(result: Result) {
|
||||
// Need to call super.onFinishRun(result) in child class
|
||||
}
|
||||
}
|
||||
|
||||
class SaveDatabaseActionRunnable(context: Context,
|
||||
database: Database,
|
||||
save: Boolean,
|
||||
nestedAction: ActionRunnable? = null)
|
||||
: SaveDatabaseRunnable(context, database, save, nestedAction) {
|
||||
|
||||
override fun run() {
|
||||
super.run()
|
||||
finishRun(true)
|
||||
override fun onFinishRun() {
|
||||
// Need to call super.onFinishRun() in child class
|
||||
mAfterSaveDatabase?.invoke(result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,44 +3,33 @@ package com.kunzisoft.keepass.database.action.node
|
||||
import android.content.Context
|
||||
import com.kunzisoft.keepass.database.action.SaveDatabaseRunnable
|
||||
import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.database.exception.LoadDatabaseException
|
||||
|
||||
abstract class ActionNodeDatabaseRunnable(
|
||||
context: Context,
|
||||
database: Database,
|
||||
private val callbackRunnable: AfterActionNodeFinishRunnable?,
|
||||
private val afterActionNodesFinish: AfterActionNodesFinish?,
|
||||
save: Boolean)
|
||||
: SaveDatabaseRunnable(context, database, save) {
|
||||
|
||||
/**
|
||||
* Function do to a node action, don't implements run() if used this
|
||||
* Function do to a node action
|
||||
*/
|
||||
abstract fun nodeAction()
|
||||
|
||||
protected fun saveDatabaseAndFinish() {
|
||||
if (result.isSuccess) {
|
||||
super.run()
|
||||
finishRun(true)
|
||||
}
|
||||
}
|
||||
|
||||
protected fun throwErrorAndFinish(throwable: LoadDatabaseException) {
|
||||
finishRun(false, throwable)
|
||||
}
|
||||
|
||||
override fun run() {
|
||||
override fun onStartRun() {
|
||||
nodeAction()
|
||||
super.onStartRun()
|
||||
}
|
||||
|
||||
/**
|
||||
* Function do get the finish node action, don't implements onFinishRun() if used this
|
||||
* Function do get the finish node action
|
||||
*/
|
||||
abstract fun nodeFinish(result: Result): ActionNodeValues
|
||||
abstract fun nodeFinish(): ActionNodesValues
|
||||
|
||||
override fun onFinishRun(result: Result) {
|
||||
callbackRunnable?.apply {
|
||||
onActionNodeFinish(nodeFinish(result))
|
||||
override fun onFinishRun() {
|
||||
super.onFinishRun()
|
||||
afterActionNodesFinish?.apply {
|
||||
onActionNodesFinish(result, nodeFinish())
|
||||
}
|
||||
super.onFinishRun(result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,17 +31,16 @@ class AddEntryRunnable constructor(
|
||||
private val mNewEntry: EntryVersioned,
|
||||
private val mParent: GroupVersioned,
|
||||
save: Boolean,
|
||||
finishRunnable: AfterActionNodeFinishRunnable?)
|
||||
: ActionNodeDatabaseRunnable(context, database, finishRunnable, save) {
|
||||
afterActionNodesFinish: AfterActionNodesFinish?)
|
||||
: ActionNodeDatabaseRunnable(context, database, afterActionNodesFinish, save) {
|
||||
|
||||
override fun nodeAction() {
|
||||
mNewEntry.touch(modified = true, touchParents = true)
|
||||
mParent.touch(modified = true, touchParents = true)
|
||||
database.addEntryTo(mNewEntry, mParent)
|
||||
saveDatabaseAndFinish()
|
||||
}
|
||||
|
||||
override fun nodeFinish(result: Result): ActionNodeValues {
|
||||
override fun nodeFinish(): ActionNodesValues {
|
||||
if (!result.isSuccess) {
|
||||
mNewEntry.parent?.let {
|
||||
database.removeEntryFrom(mNewEntry, it)
|
||||
@@ -51,6 +50,6 @@ class AddEntryRunnable constructor(
|
||||
val oldNodesReturn = ArrayList<NodeVersioned>()
|
||||
val newNodesReturn = ArrayList<NodeVersioned>()
|
||||
newNodesReturn.add(mNewEntry)
|
||||
return ActionNodeValues(result, oldNodesReturn, newNodesReturn)
|
||||
return ActionNodesValues(oldNodesReturn, newNodesReturn)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,17 +30,16 @@ class AddGroupRunnable constructor(
|
||||
private val mNewGroup: GroupVersioned,
|
||||
private val mParent: GroupVersioned,
|
||||
save: Boolean,
|
||||
afterAddNodeRunnable: AfterActionNodeFinishRunnable?)
|
||||
: ActionNodeDatabaseRunnable(context, database, afterAddNodeRunnable, save) {
|
||||
afterActionNodesFinish: AfterActionNodesFinish?)
|
||||
: ActionNodeDatabaseRunnable(context, database, afterActionNodesFinish, save) {
|
||||
|
||||
override fun nodeAction() {
|
||||
mNewGroup.touch(modified = true, touchParents = true)
|
||||
mParent.touch(modified = true, touchParents = true)
|
||||
database.addGroupTo(mNewGroup, mParent)
|
||||
saveDatabaseAndFinish()
|
||||
}
|
||||
|
||||
override fun nodeFinish(result: Result): ActionNodeValues {
|
||||
override fun nodeFinish(): ActionNodesValues {
|
||||
if (!result.isSuccess) {
|
||||
database.removeGroupFrom(mNewGroup, mParent)
|
||||
}
|
||||
@@ -48,6 +47,6 @@ class AddGroupRunnable constructor(
|
||||
val oldNodesReturn = ArrayList<NodeVersioned>()
|
||||
val newNodesReturn = ArrayList<NodeVersioned>()
|
||||
newNodesReturn.add(mNewGroup)
|
||||
return ActionNodeValues(result, oldNodesReturn, newNodesReturn)
|
||||
return ActionNodesValues(oldNodesReturn, newNodesReturn)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@ import com.kunzisoft.keepass.tasks.ActionRunnable
|
||||
* - Move : @param oldNodes empty, @param newNodes NodesToMove
|
||||
* - Update : @param oldNodes NodesToUpdate, @param newNodes NodesUpdated
|
||||
*/
|
||||
class ActionNodeValues(val result: ActionRunnable.Result, val oldNodes: List<NodeVersioned>, val newNodes: List<NodeVersioned>)
|
||||
class ActionNodesValues(val oldNodes: List<NodeVersioned>, val newNodes: List<NodeVersioned>)
|
||||
|
||||
abstract class AfterActionNodeFinishRunnable {
|
||||
abstract fun onActionNodeFinish(actionNodeValues: ActionNodeValues)
|
||||
abstract class AfterActionNodesFinish {
|
||||
abstract fun onActionNodesFinish(result: ActionRunnable.Result, actionNodesValues: ActionNodesValues)
|
||||
}
|
||||
@@ -32,20 +32,18 @@ class CopyNodesRunnable constructor(
|
||||
private val mNodesToCopy: List<NodeVersioned>,
|
||||
private val mNewParent: GroupVersioned,
|
||||
save: Boolean,
|
||||
afterAddNodeRunnable: AfterActionNodeFinishRunnable?)
|
||||
: ActionNodeDatabaseRunnable(context, database, afterAddNodeRunnable, save) {
|
||||
afterActionNodesFinish: AfterActionNodesFinish?)
|
||||
: ActionNodeDatabaseRunnable(context, database, afterActionNodesFinish, save) {
|
||||
|
||||
private var mEntriesCopied = ArrayList<EntryVersioned>()
|
||||
|
||||
override fun nodeAction() {
|
||||
|
||||
var error: LoadDatabaseException? = null
|
||||
foreachNode@ for(currentNode in mNodesToCopy) {
|
||||
|
||||
when (currentNode.type) {
|
||||
Type.GROUP -> {
|
||||
Log.e(TAG, "Copy not allowed for group")// Only finish thread
|
||||
error = CopyDatabaseGroupException()
|
||||
setError(CopyDatabaseGroupException())
|
||||
break@foreachNode
|
||||
}
|
||||
Type.ENTRY -> {
|
||||
@@ -60,24 +58,20 @@ class CopyNodesRunnable constructor(
|
||||
mEntriesCopied.add(entryCopied)
|
||||
} else {
|
||||
Log.e(TAG, "Unable to create a copy of the entry")
|
||||
error = CopyDatabaseEntryException()
|
||||
setError(CopyDatabaseEntryException())
|
||||
break@foreachNode
|
||||
}
|
||||
} else {
|
||||
// Only finish thread
|
||||
error = CopyDatabaseEntryException()
|
||||
setError(CopyDatabaseEntryException())
|
||||
break@foreachNode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (error != null)
|
||||
throwErrorAndFinish(error)
|
||||
else
|
||||
saveDatabaseAndFinish()
|
||||
}
|
||||
|
||||
override fun nodeFinish(result: Result): ActionNodeValues {
|
||||
override fun nodeFinish(): ActionNodesValues {
|
||||
if (!result.isSuccess) {
|
||||
// If we fail to save, try to delete the copy
|
||||
mEntriesCopied.forEach {
|
||||
@@ -88,7 +82,7 @@ class CopyNodesRunnable constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
return ActionNodeValues(result, mNodesToCopy, mEntriesCopied)
|
||||
return ActionNodesValues(mNodesToCopy, mEntriesCopied)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -26,8 +26,8 @@ class DeleteNodesRunnable(context: Context,
|
||||
database: Database,
|
||||
private val mNodesToDelete: List<NodeVersioned>,
|
||||
save: Boolean,
|
||||
finish: AfterActionNodeFinishRunnable)
|
||||
: ActionNodeDatabaseRunnable(context, database, finish, save) {
|
||||
afterActionNodesFinish: AfterActionNodesFinish)
|
||||
: ActionNodeDatabaseRunnable(context, database, afterActionNodesFinish, save) {
|
||||
|
||||
private var mParent: GroupVersioned? = null
|
||||
private var mCanRecycle: Boolean = false
|
||||
@@ -65,10 +65,9 @@ class DeleteNodesRunnable(context: Context,
|
||||
}
|
||||
}
|
||||
}
|
||||
saveDatabaseAndFinish()
|
||||
}
|
||||
|
||||
override fun nodeFinish(result: Result): ActionNodeValues {
|
||||
override fun nodeFinish(): ActionNodesValues {
|
||||
if (!result.isSuccess) {
|
||||
if (mCanRecycle) {
|
||||
mParent?.let {
|
||||
@@ -92,6 +91,6 @@ class DeleteNodesRunnable(context: Context,
|
||||
|
||||
// Return a copy of unchanged nodes as old param
|
||||
// and nodes deleted or moved in recycle bin as new param
|
||||
return ActionNodeValues(result, mNodesToDeleteBackup, mNodesToDelete)
|
||||
return ActionNodesValues(mNodesToDeleteBackup, mNodesToDelete)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,14 +32,13 @@ class MoveNodesRunnable constructor(
|
||||
private val mNodesToMove: List<NodeVersioned>,
|
||||
private val mNewParent: GroupVersioned,
|
||||
save: Boolean,
|
||||
afterAddNodeRunnable: AfterActionNodeFinishRunnable?)
|
||||
: ActionNodeDatabaseRunnable(context, database, afterAddNodeRunnable, save) {
|
||||
afterActionNodesFinish: AfterActionNodesFinish?)
|
||||
: ActionNodeDatabaseRunnable(context, database, afterActionNodesFinish, save) {
|
||||
|
||||
private var mOldParent: GroupVersioned? = null
|
||||
|
||||
override fun nodeAction() {
|
||||
|
||||
var error: LoadDatabaseException? = null
|
||||
foreachNode@ for(nodeToMove in mNodesToMove) {
|
||||
// Move node in new parent
|
||||
mOldParent = nodeToMove.parent
|
||||
@@ -54,7 +53,7 @@ class MoveNodesRunnable constructor(
|
||||
database.moveGroupTo(groupToMove, mNewParent)
|
||||
} else {
|
||||
// Only finish thread
|
||||
error = MoveDatabaseGroupException()
|
||||
setError(MoveDatabaseGroupException())
|
||||
break@foreachNode
|
||||
}
|
||||
}
|
||||
@@ -68,19 +67,15 @@ class MoveNodesRunnable constructor(
|
||||
database.moveEntryTo(entryToMove, mNewParent)
|
||||
} else {
|
||||
// Only finish thread
|
||||
error = MoveDatabaseEntryException()
|
||||
setError(MoveDatabaseEntryException())
|
||||
break@foreachNode
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (error != null)
|
||||
throwErrorAndFinish(error)
|
||||
else
|
||||
saveDatabaseAndFinish()
|
||||
}
|
||||
|
||||
override fun nodeFinish(result: Result): ActionNodeValues {
|
||||
override fun nodeFinish(): ActionNodesValues {
|
||||
if (!result.isSuccess) {
|
||||
try {
|
||||
mNodesToMove.forEach { nodeToMove ->
|
||||
@@ -97,7 +92,7 @@ class MoveNodesRunnable constructor(
|
||||
Log.i(TAG, "Unable to replace the node")
|
||||
}
|
||||
}
|
||||
return ActionNodeValues(result, ArrayList(), mNodesToMove)
|
||||
return ActionNodesValues(ArrayList(), mNodesToMove)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -30,8 +30,8 @@ class UpdateEntryRunnable constructor(
|
||||
private val mOldEntry: EntryVersioned,
|
||||
private val mNewEntry: EntryVersioned,
|
||||
save: Boolean,
|
||||
finishRunnable: AfterActionNodeFinishRunnable?)
|
||||
: ActionNodeDatabaseRunnable(context, database, finishRunnable, save) {
|
||||
afterActionNodesFinish: AfterActionNodesFinish?)
|
||||
: ActionNodeDatabaseRunnable(context, database, afterActionNodesFinish, save) {
|
||||
|
||||
// Keep backup of original values in case save fails
|
||||
private var mBackupEntryHistory: EntryVersioned = EntryVersioned(mOldEntry)
|
||||
@@ -50,11 +50,9 @@ class UpdateEntryRunnable constructor(
|
||||
|
||||
// Only change data in index
|
||||
database.updateEntry(mOldEntry)
|
||||
|
||||
saveDatabaseAndFinish()
|
||||
}
|
||||
|
||||
override fun nodeFinish(result: Result): ActionNodeValues {
|
||||
override fun nodeFinish(): ActionNodesValues {
|
||||
if (!result.isSuccess) {
|
||||
mOldEntry.updateWith(mBackupEntryHistory)
|
||||
// If we fail to save, back out changes to global structure
|
||||
@@ -65,6 +63,6 @@ class UpdateEntryRunnable constructor(
|
||||
oldNodesReturn.add(mBackupEntryHistory)
|
||||
val newNodesReturn = ArrayList<NodeVersioned>()
|
||||
newNodesReturn.add(mOldEntry)
|
||||
return ActionNodeValues(result, oldNodesReturn, newNodesReturn)
|
||||
return ActionNodesValues(oldNodesReturn, newNodesReturn)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,8 +30,8 @@ class UpdateGroupRunnable constructor(
|
||||
private val mOldGroup: GroupVersioned,
|
||||
private val mNewGroup: GroupVersioned,
|
||||
save: Boolean,
|
||||
finishRunnable: AfterActionNodeFinishRunnable?)
|
||||
: ActionNodeDatabaseRunnable(context, database, finishRunnable, save) {
|
||||
afterActionNodesFinish: AfterActionNodesFinish?)
|
||||
: ActionNodeDatabaseRunnable(context, database, afterActionNodesFinish, save) {
|
||||
|
||||
// Keep backup of original values in case save fails
|
||||
private val mBackupGroup: GroupVersioned = GroupVersioned(mOldGroup)
|
||||
@@ -47,11 +47,9 @@ class UpdateGroupRunnable constructor(
|
||||
|
||||
// Only change data in index
|
||||
database.updateGroup(mOldGroup)
|
||||
|
||||
saveDatabaseAndFinish()
|
||||
}
|
||||
|
||||
override fun nodeFinish(result: Result): ActionNodeValues {
|
||||
override fun nodeFinish(): ActionNodesValues {
|
||||
if (!result.isSuccess) {
|
||||
// If we fail to save, back out changes to global structure
|
||||
mOldGroup.updateWith(mBackupGroup)
|
||||
@@ -62,6 +60,6 @@ class UpdateGroupRunnable constructor(
|
||||
oldNodesReturn.add(mBackupGroup)
|
||||
val newNodesReturn = ArrayList<NodeVersioned>()
|
||||
newNodesReturn.add(mOldGroup)
|
||||
return ActionNodeValues(result, oldNodesReturn, newNodesReturn)
|
||||
return ActionNodesValues(oldNodesReturn, newNodesReturn)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,14 +6,12 @@ import android.os.AsyncTask
|
||||
import android.os.Binder
|
||||
import android.os.Bundle
|
||||
import android.os.IBinder
|
||||
import android.util.Log
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.app.database.CipherDatabaseEntity
|
||||
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
|
||||
import com.kunzisoft.keepass.database.action.AssignPasswordInDatabaseRunnable
|
||||
import com.kunzisoft.keepass.database.action.CreateDatabaseRunnable
|
||||
import com.kunzisoft.keepass.database.action.LoadDatabaseRunnable
|
||||
import com.kunzisoft.keepass.database.action.SaveDatabaseActionRunnable
|
||||
import com.kunzisoft.keepass.database.action.SaveDatabaseRunnable
|
||||
import com.kunzisoft.keepass.database.action.node.*
|
||||
import com.kunzisoft.keepass.database.element.*
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
@@ -185,22 +183,7 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
|
||||
intent.getStringExtra(MASTER_PASSWORD_KEY),
|
||||
intent.getBooleanExtra(KEY_FILE_CHECKED_KEY, false),
|
||||
keyFileUri,
|
||||
true, // TODO get readonly
|
||||
object: ActionRunnable() {
|
||||
override fun run() {
|
||||
finishRun(true)
|
||||
}
|
||||
|
||||
override fun onFinishRun(result: Result) {
|
||||
if (result.isSuccess) {
|
||||
// Add database to recent files
|
||||
FileDatabaseHistoryAction.getInstance(applicationContext)
|
||||
.addOrUpdateDatabaseUri(databaseUri, keyFileUri)
|
||||
} else {
|
||||
Log.e(TAG, "Unable to create the database")
|
||||
}
|
||||
}
|
||||
}
|
||||
true // TODO get readonly
|
||||
)
|
||||
} else {
|
||||
return null
|
||||
@@ -235,6 +218,7 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
|
||||
intent.getBooleanExtra(FIX_DUPLICATE_UUID_KEY, false),
|
||||
this
|
||||
) { result ->
|
||||
// Add each info to reload database after thrown duplicate UUID exception
|
||||
result.data = Bundle().apply {
|
||||
putParcelable(DATABASE_URI_KEY, databaseUri)
|
||||
putString(MASTER_PASSWORD_KEY, masterPassword)
|
||||
@@ -266,13 +250,13 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
|
||||
}
|
||||
}
|
||||
|
||||
private inner class AfterActionNodeRunnable : AfterActionNodeFinishRunnable() {
|
||||
override fun onActionNodeFinish(actionNodeValues: ActionNodeValues) {
|
||||
// TODO Encapsulate
|
||||
val bundle = actionNodeValues.result.data ?: Bundle()
|
||||
bundle.putBundle(OLD_NODES_KEY, getBundleFromListNodes(actionNodeValues.oldNodes))
|
||||
bundle.putBundle(NEW_NODES_KEY, getBundleFromListNodes(actionNodeValues.newNodes))
|
||||
actionNodeValues.result.data = bundle
|
||||
private inner class AfterActionNodesRunnable : AfterActionNodesFinish() {
|
||||
override fun onActionNodesFinish(result: ActionRunnable.Result,
|
||||
actionNodesValues: ActionNodesValues) {
|
||||
val bundle = result.data ?: Bundle()
|
||||
bundle.putBundle(OLD_NODES_KEY, getBundleFromListNodes(actionNodesValues.oldNodes))
|
||||
bundle.putBundle(NEW_NODES_KEY, getBundleFromListNodes(actionNodesValues.newNodes))
|
||||
result.data = bundle
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,7 +272,7 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
|
||||
intent.getParcelableExtra(GROUP_KEY),
|
||||
parent,
|
||||
intent.getBooleanExtra(SAVE_DATABASE_KEY, false),
|
||||
AfterActionNodeRunnable())
|
||||
AfterActionNodesRunnable())
|
||||
}
|
||||
} else {
|
||||
null
|
||||
@@ -308,7 +292,7 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
|
||||
oldGroup,
|
||||
newGroup,
|
||||
intent.getBooleanExtra(SAVE_DATABASE_KEY, false),
|
||||
AfterActionNodeRunnable())
|
||||
AfterActionNodesRunnable())
|
||||
}
|
||||
} else {
|
||||
null
|
||||
@@ -327,7 +311,7 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
|
||||
intent.getParcelableExtra(ENTRY_KEY),
|
||||
parent,
|
||||
intent.getBooleanExtra(SAVE_DATABASE_KEY, false),
|
||||
AfterActionNodeRunnable())
|
||||
AfterActionNodesRunnable())
|
||||
}
|
||||
} else {
|
||||
null
|
||||
@@ -347,7 +331,7 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
|
||||
oldEntry,
|
||||
newEntry,
|
||||
intent.getBooleanExtra(SAVE_DATABASE_KEY, false),
|
||||
AfterActionNodeRunnable())
|
||||
AfterActionNodesRunnable())
|
||||
}
|
||||
} else {
|
||||
null
|
||||
@@ -367,7 +351,7 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
|
||||
getListNodesFromBundle(database, intent.extras!!),
|
||||
newParent,
|
||||
intent.getBooleanExtra(SAVE_DATABASE_KEY, false),
|
||||
AfterActionNodeRunnable())
|
||||
AfterActionNodesRunnable())
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -388,7 +372,7 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
|
||||
getListNodesFromBundle(database, intent.extras!!),
|
||||
newParent,
|
||||
intent.getBooleanExtra(SAVE_DATABASE_KEY, false),
|
||||
AfterActionNodeRunnable())
|
||||
AfterActionNodesRunnable())
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -406,7 +390,7 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
|
||||
database,
|
||||
getListNodesFromBundle(database, intent.extras!!),
|
||||
intent.getBooleanExtra(SAVE_DATABASE_KEY, false),
|
||||
AfterActionNodeRunnable())
|
||||
AfterActionNodesRunnable())
|
||||
|
||||
} else {
|
||||
null
|
||||
@@ -414,14 +398,14 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
|
||||
}
|
||||
|
||||
private fun buildDatabaseSaveElementActionTask(intent: Intent): ActionRunnable? {
|
||||
return SaveDatabaseActionRunnable(this,
|
||||
return SaveDatabaseRunnable(this,
|
||||
Database.getInstance(),
|
||||
true,
|
||||
object: ActionRunnable() {
|
||||
override fun onFinishRun(result: Result) {
|
||||
true
|
||||
).apply {
|
||||
mAfterSaveDatabase = { result ->
|
||||
result.data = intent.extras
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private class ActionRunnableAsyncTask(private val progressTaskUpdater: ProgressTaskUpdater,
|
||||
|
||||
@@ -25,58 +25,37 @@ import com.kunzisoft.keepass.database.exception.LoadDatabaseException
|
||||
/**
|
||||
* Callback after a task is completed.
|
||||
*/
|
||||
abstract class ActionRunnable(private var nestedActionRunnable: ActionRunnable? = null,
|
||||
private var executeNestedActionIfResultFalse: Boolean = false)
|
||||
: Runnable {
|
||||
abstract class ActionRunnable: Runnable {
|
||||
|
||||
var result: Result = Result()
|
||||
|
||||
private fun execute() {
|
||||
nestedActionRunnable?.let {
|
||||
// Pass on result on call finish
|
||||
it.result = result
|
||||
it.run()
|
||||
}
|
||||
onFinishRun(result)
|
||||
}
|
||||
|
||||
override fun run() {
|
||||
execute()
|
||||
onStartRun()
|
||||
onActionRun()
|
||||
onFinishRun()
|
||||
}
|
||||
|
||||
/**
|
||||
* If [success] or [executeNestedActionIfResultFalse] true,
|
||||
* launch the nested action runnable if exists and finish,
|
||||
* else directly finish
|
||||
*/
|
||||
protected fun finishRun(isSuccess: Boolean,
|
||||
message: String? = null) {
|
||||
finishRun(isSuccess, null, message)
|
||||
}
|
||||
abstract fun onStartRun()
|
||||
|
||||
/**
|
||||
* If [success] or [executeNestedActionIfResultFalse] true,
|
||||
* launch the nested action runnable if exists and finish,
|
||||
* else directly finish
|
||||
*/
|
||||
protected fun finishRun(isSuccess: Boolean,
|
||||
exception: LoadDatabaseException?,
|
||||
message: String? = null) {
|
||||
result.isSuccess = isSuccess
|
||||
result.exception = exception
|
||||
result.message = message
|
||||
if (isSuccess || executeNestedActionIfResultFalse) {
|
||||
execute()
|
||||
}
|
||||
else
|
||||
onFinishRun(result)
|
||||
}
|
||||
abstract fun onActionRun()
|
||||
|
||||
/**
|
||||
* Method called when the action is finished
|
||||
* @param result 'true' if success action, 'false' elsewhere, with message
|
||||
*/
|
||||
abstract fun onFinishRun(result: Result)
|
||||
abstract fun onFinishRun()
|
||||
|
||||
protected fun setError(message: String? = null) {
|
||||
setError(null, message)
|
||||
}
|
||||
|
||||
protected fun setError(exception: LoadDatabaseException?,
|
||||
message: String? = null) {
|
||||
result.isSuccess = false
|
||||
result.exception = exception
|
||||
result.message = message
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class to manage result from ActionRunnable
|
||||
@@ -84,29 +63,5 @@ abstract class ActionRunnable(private var nestedActionRunnable: ActionRunnable?
|
||||
data class Result(var isSuccess: Boolean = true,
|
||||
var message: String? = null,
|
||||
var exception: LoadDatabaseException? = null,
|
||||
var data: Bundle? = null) {
|
||||
|
||||
fun toBundle(): Bundle {
|
||||
return Bundle().apply {
|
||||
putBoolean(IS_SUCCESS_KEY, isSuccess)
|
||||
putString(MESSAGE_KEY, message)
|
||||
putSerializable(EXCEPTION_KEY, exception)
|
||||
putBundle(DATA_KEY, data)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val IS_SUCCESS_KEY = "IS_SUCCESS_KEY"
|
||||
private const val MESSAGE_KEY = "MESSAGE_KEY"
|
||||
private const val EXCEPTION_KEY = "EXCEPTION_KEY"
|
||||
private const val DATA_KEY = "DATA_KEY"
|
||||
|
||||
fun fromBundle(bundle: Bundle): Result {
|
||||
return Result(bundle.getBoolean(IS_SUCCESS_KEY),
|
||||
bundle.getString(MESSAGE_KEY),
|
||||
bundle.getSerializable(EXCEPTION_KEY) as LoadDatabaseException?,
|
||||
bundle.getBundle(DATA_KEY))
|
||||
}
|
||||
}
|
||||
}
|
||||
var data: Bundle? = null)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user