mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Add database reloading #794
This commit is contained in:
@@ -53,6 +53,7 @@ import com.kunzisoft.keepass.model.StreamDirection
|
|||||||
import com.kunzisoft.keepass.notifications.AttachmentFileNotificationService
|
import com.kunzisoft.keepass.notifications.AttachmentFileNotificationService
|
||||||
import com.kunzisoft.keepass.notifications.ClipboardEntryNotificationService
|
import com.kunzisoft.keepass.notifications.ClipboardEntryNotificationService
|
||||||
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_DELETE_ENTRY_HISTORY
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_DELETE_ENTRY_HISTORY
|
||||||
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_RELOAD_TASK
|
||||||
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_RESTORE_ENTRY_HISTORY
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_RESTORE_ENTRY_HISTORY
|
||||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||||
import com.kunzisoft.keepass.tasks.AttachmentFileBinderManager
|
import com.kunzisoft.keepass.tasks.AttachmentFileBinderManager
|
||||||
@@ -151,6 +152,10 @@ class EntryActivity : LockingActivity() {
|
|||||||
if (result.isSuccess)
|
if (result.isSuccess)
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
ACTION_DATABASE_RELOAD_TASK -> {
|
||||||
|
// Close the current activity
|
||||||
|
finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
coordinatorLayout?.showActionError(result)
|
coordinatorLayout?.showActionError(result)
|
||||||
}
|
}
|
||||||
@@ -501,6 +506,9 @@ class EntryActivity : LockingActivity() {
|
|||||||
R.id.menu_save_database -> {
|
R.id.menu_save_database -> {
|
||||||
mProgressDatabaseTaskProvider?.startDatabaseSave(!mReadOnly)
|
mProgressDatabaseTaskProvider?.startDatabaseSave(!mReadOnly)
|
||||||
}
|
}
|
||||||
|
R.id.menu_reload_database -> {
|
||||||
|
mProgressDatabaseTaskProvider?.startDatabaseReload(false)
|
||||||
|
}
|
||||||
android.R.id.home -> finish() // close this activity and return to preview activity (if there is any)
|
android.R.id.home -> finish() // close this activity and return to preview activity (if there is any)
|
||||||
}
|
}
|
||||||
return super.onOptionsItemSelected(item)
|
return super.onOptionsItemSelected(item)
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ import com.kunzisoft.keepass.notifications.AttachmentFileNotificationService
|
|||||||
import com.kunzisoft.keepass.notifications.ClipboardEntryNotificationService
|
import com.kunzisoft.keepass.notifications.ClipboardEntryNotificationService
|
||||||
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService
|
||||||
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_CREATE_ENTRY_TASK
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_CREATE_ENTRY_TASK
|
||||||
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_RELOAD_TASK
|
||||||
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_UPDATE_ENTRY_TASK
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_UPDATE_ENTRY_TASK
|
||||||
import com.kunzisoft.keepass.notifications.KeyboardEntryNotificationService
|
import com.kunzisoft.keepass.notifications.KeyboardEntryNotificationService
|
||||||
import com.kunzisoft.keepass.otp.OtpElement
|
import com.kunzisoft.keepass.otp.OtpElement
|
||||||
@@ -335,6 +336,10 @@ class EntryEditActivity : LockingActivity(),
|
|||||||
Log.e(TAG, "Unable to retrieve entry after database action", e)
|
Log.e(TAG, "Unable to retrieve entry after database action", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ACTION_DATABASE_RELOAD_TASK -> {
|
||||||
|
// Close the current activity
|
||||||
|
finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
coordinatorLayout?.showActionError(result)
|
coordinatorLayout?.showActionError(result)
|
||||||
}
|
}
|
||||||
@@ -610,13 +615,7 @@ class EntryEditActivity : LockingActivity(),
|
|||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
super.onCreateOptionsMenu(menu)
|
super.onCreateOptionsMenu(menu)
|
||||||
|
MenuUtil.contributionMenuInflater(menuInflater, menu)
|
||||||
val inflater = menuInflater
|
|
||||||
inflater.inflate(R.menu.database, menu)
|
|
||||||
// Save database not needed here
|
|
||||||
menu.findItem(R.id.menu_save_database)?.isVisible = false
|
|
||||||
MenuUtil.contributionMenuInflater(inflater, menu)
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -673,9 +672,6 @@ class EntryEditActivity : LockingActivity(),
|
|||||||
|
|
||||||
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
override fun onOptionsItemSelected(item: MenuItem): Boolean {
|
||||||
when (item.itemId) {
|
when (item.itemId) {
|
||||||
R.id.menu_save_database -> {
|
|
||||||
mProgressDatabaseTaskProvider?.startDatabaseSave(!mReadOnly)
|
|
||||||
}
|
|
||||||
R.id.menu_contribute -> {
|
R.id.menu_contribute -> {
|
||||||
MenuUtil.onContributionItemSelected(this)
|
MenuUtil.onContributionItemSelected(this)
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Compa
|
|||||||
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_CREATE_GROUP_TASK
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_CREATE_GROUP_TASK
|
||||||
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_DELETE_NODES_TASK
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_DELETE_NODES_TASK
|
||||||
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_MOVE_NODES_TASK
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_MOVE_NODES_TASK
|
||||||
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_RELOAD_TASK
|
||||||
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_UPDATE_ENTRY_TASK
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_UPDATE_ENTRY_TASK
|
||||||
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_UPDATE_GROUP_TASK
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_UPDATE_GROUP_TASK
|
||||||
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.NEW_NODES_KEY
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.NEW_NODES_KEY
|
||||||
@@ -342,6 +343,11 @@ class GroupActivity : LockingActivity(),
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ACTION_DATABASE_RELOAD_TASK -> {
|
||||||
|
// Reload the current activity
|
||||||
|
startActivity(intent)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
coordinatorLayout?.showActionError(result)
|
coordinatorLayout?.showActionError(result)
|
||||||
@@ -1003,6 +1009,10 @@ class GroupActivity : LockingActivity(),
|
|||||||
mProgressDatabaseTaskProvider?.startDatabaseSave(!mReadOnly)
|
mProgressDatabaseTaskProvider?.startDatabaseSave(!mReadOnly)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
R.id.menu_reload_database -> {
|
||||||
|
mProgressDatabaseTaskProvider?.startDatabaseReload(false)
|
||||||
|
return true
|
||||||
|
}
|
||||||
R.id.menu_empty_recycle_bin -> {
|
R.id.menu_empty_recycle_bin -> {
|
||||||
mCurrentGroup?.getChildren()?.let { listChildren ->
|
mCurrentGroup?.getChildren()?.let { listChildren ->
|
||||||
// Automatically delete all elements
|
// Automatically delete all elements
|
||||||
|
|||||||
@@ -720,7 +720,7 @@ open class PasswordActivity : SpecialModeActivity(), AdvancedUnlockFragment.Buil
|
|||||||
when (resultCode) {
|
when (resultCode) {
|
||||||
LockingActivity.RESULT_EXIT_LOCK -> {
|
LockingActivity.RESULT_EXIT_LOCK -> {
|
||||||
clearCredentialsViews()
|
clearCredentialsViews()
|
||||||
Database.getInstance().closeAndClear(UriUtil.getBinaryDir(this))
|
Database.getInstance().clearAndClose(UriUtil.getBinaryDir(this))
|
||||||
}
|
}
|
||||||
Activity.RESULT_CANCELED -> {
|
Activity.RESULT_CANCELED -> {
|
||||||
clearCredentialsViews()
|
clearCredentialsViews()
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ class App : MultiDexApplication() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onTerminate() {
|
override fun onTerminate() {
|
||||||
Database.getInstance().closeAndClear(UriUtil.getBinaryDir(this))
|
Database.getInstance().clearAndClose(UriUtil.getBinaryDir(this))
|
||||||
super.onTerminate()
|
super.onTerminate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
|
|||||||
import com.kunzisoft.keepass.database.element.Database
|
import com.kunzisoft.keepass.database.element.Database
|
||||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||||
import com.kunzisoft.keepass.utils.UriUtil
|
import com.kunzisoft.keepass.utils.UriUtil
|
||||||
import com.kunzisoft.keepass.utils.closeDatabase
|
|
||||||
|
|
||||||
class CreateDatabaseRunnable(context: Context,
|
class CreateDatabaseRunnable(context: Context,
|
||||||
private val mDatabase: Database,
|
private val mDatabase: Database,
|
||||||
@@ -47,7 +46,7 @@ class CreateDatabaseRunnable(context: Context,
|
|||||||
createData(mDatabaseUri, databaseName, rootName)
|
createData(mDatabaseUri, databaseName, rootName)
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
mDatabase.closeAndClear(UriUtil.getBinaryDir(context))
|
mDatabase.clearAndClose(UriUtil.getBinaryDir(context))
|
||||||
setError(e)
|
setError(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,6 @@ import com.kunzisoft.keepass.settings.PreferencesUtil
|
|||||||
import com.kunzisoft.keepass.tasks.ActionRunnable
|
import com.kunzisoft.keepass.tasks.ActionRunnable
|
||||||
import com.kunzisoft.keepass.tasks.ProgressTaskUpdater
|
import com.kunzisoft.keepass.tasks.ProgressTaskUpdater
|
||||||
import com.kunzisoft.keepass.utils.UriUtil
|
import com.kunzisoft.keepass.utils.UriUtil
|
||||||
import com.kunzisoft.keepass.utils.closeDatabase
|
|
||||||
|
|
||||||
class LoadDatabaseRunnable(private val context: Context,
|
class LoadDatabaseRunnable(private val context: Context,
|
||||||
private val mDatabase: Database,
|
private val mDatabase: Database,
|
||||||
@@ -47,7 +46,7 @@ class LoadDatabaseRunnable(private val context: Context,
|
|||||||
|
|
||||||
override fun onStartRun() {
|
override fun onStartRun() {
|
||||||
// Clear before we load
|
// Clear before we load
|
||||||
mDatabase.closeAndClear(UriUtil.getBinaryDir(context))
|
mDatabase.clearAndClose(UriUtil.getBinaryDir(context))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onActionRun() {
|
override fun onActionRun() {
|
||||||
@@ -83,7 +82,7 @@ class LoadDatabaseRunnable(private val context: Context,
|
|||||||
// Register the current time to init the lock timer
|
// Register the current time to init the lock timer
|
||||||
PreferencesUtil.saveCurrentTime(context)
|
PreferencesUtil.saveCurrentTime(context)
|
||||||
} else {
|
} else {
|
||||||
mDatabase.closeAndClear(UriUtil.getBinaryDir(context))
|
mDatabase.clearAndClose(UriUtil.getBinaryDir(context))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Compa
|
|||||||
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_DELETE_ENTRY_HISTORY
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_DELETE_ENTRY_HISTORY
|
||||||
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_DELETE_NODES_TASK
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_DELETE_NODES_TASK
|
||||||
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_LOAD_TASK
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_LOAD_TASK
|
||||||
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_RELOAD_TASK
|
||||||
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_MOVE_NODES_TASK
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_MOVE_NODES_TASK
|
||||||
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_REMOVE_UNLINKED_DATA_TASK
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_REMOVE_UNLINKED_DATA_TASK
|
||||||
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_RESTORE_ENTRY_HISTORY
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_RESTORE_ENTRY_HISTORY
|
||||||
@@ -294,6 +295,13 @@ class ProgressDatabaseTaskProvider(private val activity: FragmentActivity) {
|
|||||||
, ACTION_DATABASE_LOAD_TASK)
|
, ACTION_DATABASE_LOAD_TASK)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun startDatabaseReload(fixDuplicateUuid: Boolean) {
|
||||||
|
start(Bundle().apply {
|
||||||
|
putBoolean(DatabaseTaskNotificationService.FIX_DUPLICATE_UUID_KEY, fixDuplicateUuid)
|
||||||
|
}
|
||||||
|
, ACTION_DATABASE_RELOAD_TASK)
|
||||||
|
}
|
||||||
|
|
||||||
fun startDatabaseAssignPassword(databaseUri: Uri,
|
fun startDatabaseAssignPassword(databaseUri: Uri,
|
||||||
masterPasswordChecked: Boolean,
|
masterPasswordChecked: Boolean,
|
||||||
masterPassword: String?,
|
masterPassword: String?,
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 Jeremy Jamet / Kunzisoft.
|
||||||
|
*
|
||||||
|
* This file is part of KeePassDX.
|
||||||
|
*
|
||||||
|
* KeePassDX is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* KeePassDX is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with KeePassDX. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
package com.kunzisoft.keepass.database.action
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import com.kunzisoft.keepass.database.element.Database
|
||||||
|
import com.kunzisoft.keepass.database.exception.DuplicateUuidDatabaseException
|
||||||
|
import com.kunzisoft.keepass.database.exception.LoadDatabaseException
|
||||||
|
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||||
|
import com.kunzisoft.keepass.tasks.ActionRunnable
|
||||||
|
import com.kunzisoft.keepass.tasks.ProgressTaskUpdater
|
||||||
|
import com.kunzisoft.keepass.utils.UriUtil
|
||||||
|
|
||||||
|
class ReloadDatabaseRunnable(private val context: Context,
|
||||||
|
private val mDatabase: Database,
|
||||||
|
private val mFixDuplicateUUID: Boolean,
|
||||||
|
private val progressTaskUpdater: ProgressTaskUpdater?,
|
||||||
|
private val mLoadDatabaseResult: ((Result) -> Unit)?)
|
||||||
|
: ActionRunnable() {
|
||||||
|
|
||||||
|
override fun onStartRun() {
|
||||||
|
// Clear before we load
|
||||||
|
mDatabase.clear(UriUtil.getBinaryDir(context))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActionRun() {
|
||||||
|
try {
|
||||||
|
mDatabase.reloadData(context.contentResolver,
|
||||||
|
UriUtil.getBinaryDir(context),
|
||||||
|
mFixDuplicateUUID,
|
||||||
|
progressTaskUpdater)
|
||||||
|
}
|
||||||
|
catch (e: DuplicateUuidDatabaseException) {
|
||||||
|
setError(e)
|
||||||
|
}
|
||||||
|
catch (e: LoadDatabaseException) {
|
||||||
|
setError(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.isSuccess) {
|
||||||
|
// Register the current time to init the lock timer
|
||||||
|
PreferencesUtil.saveCurrentTime(context)
|
||||||
|
} else {
|
||||||
|
mDatabase.clearAndClose(UriUtil.getBinaryDir(context))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFinishRun() {
|
||||||
|
mLoadDatabaseResult?.invoke(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,10 +31,7 @@ import com.kunzisoft.keepass.database.element.node.NodeId
|
|||||||
import com.kunzisoft.keepass.database.element.node.NodeIdInt
|
import com.kunzisoft.keepass.database.element.node.NodeIdInt
|
||||||
import com.kunzisoft.keepass.database.element.node.NodeIdUUID
|
import com.kunzisoft.keepass.database.element.node.NodeIdUUID
|
||||||
import com.kunzisoft.keepass.database.element.security.EncryptionAlgorithm
|
import com.kunzisoft.keepass.database.element.security.EncryptionAlgorithm
|
||||||
import com.kunzisoft.keepass.database.exception.DatabaseOutputException
|
import com.kunzisoft.keepass.database.exception.*
|
||||||
import com.kunzisoft.keepass.database.exception.FileNotFoundDatabaseException
|
|
||||||
import com.kunzisoft.keepass.database.exception.LoadDatabaseException
|
|
||||||
import com.kunzisoft.keepass.database.exception.SignatureDatabaseException
|
|
||||||
import com.kunzisoft.keepass.database.file.DatabaseHeaderKDB
|
import com.kunzisoft.keepass.database.file.DatabaseHeaderKDB
|
||||||
import com.kunzisoft.keepass.database.file.DatabaseHeaderKDBX
|
import com.kunzisoft.keepass.database.file.DatabaseHeaderKDBX
|
||||||
import com.kunzisoft.keepass.database.file.input.DatabaseInputKDB
|
import com.kunzisoft.keepass.database.file.input.DatabaseInputKDB
|
||||||
@@ -330,29 +327,11 @@ class Database {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Throws(LoadDatabaseException::class)
|
@Throws(LoadDatabaseException::class)
|
||||||
fun loadData(uri: Uri, password: String?, keyfile: Uri?,
|
private fun readDatabaseStream(contentResolver: ContentResolver, uri: Uri,
|
||||||
readOnly: Boolean,
|
openDatabaseKDB: (InputStream) -> DatabaseKDB,
|
||||||
contentResolver: ContentResolver,
|
openDatabaseKDBX: (InputStream) -> DatabaseKDBX) {
|
||||||
cacheDirectory: File,
|
|
||||||
fixDuplicateUUID: Boolean,
|
|
||||||
progressTaskUpdater: ProgressTaskUpdater?) {
|
|
||||||
|
|
||||||
this.fileUri = uri
|
|
||||||
isReadOnly = readOnly
|
|
||||||
if (uri.scheme == "file") {
|
|
||||||
val file = File(uri.path!!)
|
|
||||||
isReadOnly = !file.canWrite()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pass KeyFile Uri as InputStreams
|
|
||||||
var databaseInputStream: InputStream? = null
|
var databaseInputStream: InputStream? = null
|
||||||
var keyFileInputStream: InputStream? = null
|
|
||||||
try {
|
try {
|
||||||
// Get keyFile inputStream
|
|
||||||
keyfile?.let {
|
|
||||||
keyFileInputStream = UriUtil.getUriInputStream(contentResolver, keyfile)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load Data, pass Uris as InputStreams
|
// Load Data, pass Uris as InputStreams
|
||||||
val databaseStream = UriUtil.getUriInputStream(contentResolver, uri)
|
val databaseStream = UriUtil.getUriInputStream(contentResolver, uri)
|
||||||
?: throw IOException("Database input stream cannot be retrieve")
|
?: throw IOException("Database input stream cannot be retrieve")
|
||||||
@@ -374,22 +353,10 @@ class Database {
|
|||||||
|
|
||||||
when {
|
when {
|
||||||
// Header of database KDB
|
// Header of database KDB
|
||||||
DatabaseHeaderKDB.matchesHeader(sig1, sig2) -> setDatabaseKDB(DatabaseInputKDB(
|
DatabaseHeaderKDB.matchesHeader(sig1, sig2) -> setDatabaseKDB(openDatabaseKDB(databaseInputStream))
|
||||||
cacheDirectory,
|
|
||||||
fixDuplicateUUID)
|
|
||||||
.openDatabase(databaseInputStream,
|
|
||||||
password,
|
|
||||||
keyFileInputStream,
|
|
||||||
progressTaskUpdater))
|
|
||||||
|
|
||||||
// Header of database KDBX
|
// Header of database KDBX
|
||||||
DatabaseHeaderKDBX.matchesHeader(sig1, sig2) -> setDatabaseKDBX(DatabaseInputKDBX(
|
DatabaseHeaderKDBX.matchesHeader(sig1, sig2) -> setDatabaseKDBX(openDatabaseKDBX(databaseInputStream))
|
||||||
cacheDirectory,
|
|
||||||
fixDuplicateUUID)
|
|
||||||
.openDatabase(databaseInputStream,
|
|
||||||
password,
|
|
||||||
keyFileInputStream,
|
|
||||||
progressTaskUpdater))
|
|
||||||
|
|
||||||
// Header not recognized
|
// Header not recognized
|
||||||
else -> throw SignatureDatabaseException()
|
else -> throw SignatureDatabaseException()
|
||||||
@@ -397,17 +364,92 @@ class Database {
|
|||||||
|
|
||||||
this.mSearchHelper = SearchHelper()
|
this.mSearchHelper = SearchHelper()
|
||||||
loaded = true
|
loaded = true
|
||||||
|
|
||||||
} catch (e: LoadDatabaseException) {
|
} catch (e: LoadDatabaseException) {
|
||||||
throw e
|
throw e
|
||||||
|
} finally {
|
||||||
|
databaseInputStream?.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(LoadDatabaseException::class)
|
||||||
|
fun loadData(uri: Uri, password: String?, keyfile: Uri?,
|
||||||
|
readOnly: Boolean,
|
||||||
|
contentResolver: ContentResolver,
|
||||||
|
cacheDirectory: File,
|
||||||
|
fixDuplicateUUID: Boolean,
|
||||||
|
progressTaskUpdater: ProgressTaskUpdater?) {
|
||||||
|
|
||||||
|
// Save database URI
|
||||||
|
this.fileUri = uri
|
||||||
|
|
||||||
|
// Check if the file is writable
|
||||||
|
this.isReadOnly = readOnly
|
||||||
|
if (uri.scheme == "file") {
|
||||||
|
val file = File(uri.path!!)
|
||||||
|
isReadOnly = !file.canWrite()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass KeyFile Uri as InputStreams
|
||||||
|
var keyFileInputStream: InputStream? = null
|
||||||
|
try {
|
||||||
|
// Get keyFile inputStream
|
||||||
|
keyfile?.let {
|
||||||
|
keyFileInputStream = UriUtil.getUriInputStream(contentResolver, keyfile)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read database stream for the first time
|
||||||
|
readDatabaseStream(contentResolver, uri,
|
||||||
|
{ databaseInputStream ->
|
||||||
|
DatabaseInputKDB(cacheDirectory)
|
||||||
|
.openDatabase(databaseInputStream,
|
||||||
|
password,
|
||||||
|
keyFileInputStream,
|
||||||
|
fixDuplicateUUID,
|
||||||
|
progressTaskUpdater)
|
||||||
|
},
|
||||||
|
{ databaseInputStream ->
|
||||||
|
DatabaseInputKDBX(cacheDirectory)
|
||||||
|
.openDatabase(databaseInputStream,
|
||||||
|
password,
|
||||||
|
keyFileInputStream,
|
||||||
|
fixDuplicateUUID,
|
||||||
|
progressTaskUpdater)
|
||||||
|
}
|
||||||
|
)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
throw FileNotFoundDatabaseException()
|
throw FileNotFoundDatabaseException()
|
||||||
} finally {
|
} finally {
|
||||||
keyFileInputStream?.close()
|
keyFileInputStream?.close()
|
||||||
databaseInputStream?.close()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Throws(LoadDatabaseException::class)
|
||||||
|
fun reloadData(contentResolver: ContentResolver,
|
||||||
|
cacheDirectory: File,
|
||||||
|
fixDuplicateUUID: Boolean,
|
||||||
|
progressTaskUpdater: ProgressTaskUpdater?) {
|
||||||
|
|
||||||
|
// Retrieve the stream from the old database URI
|
||||||
|
fileUri?.let { oldDatabaseUri ->
|
||||||
|
readDatabaseStream(contentResolver, oldDatabaseUri,
|
||||||
|
{ databaseInputStream ->
|
||||||
|
DatabaseInputKDB(cacheDirectory)
|
||||||
|
.openDatabase(databaseInputStream,
|
||||||
|
masterKey,
|
||||||
|
fixDuplicateUUID,
|
||||||
|
progressTaskUpdater)
|
||||||
|
},
|
||||||
|
{ databaseInputStream ->
|
||||||
|
DatabaseInputKDBX(cacheDirectory)
|
||||||
|
.openDatabase(databaseInputStream,
|
||||||
|
masterKey,
|
||||||
|
fixDuplicateUUID,
|
||||||
|
progressTaskUpdater)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
} ?: throw IODatabaseException()
|
||||||
|
}
|
||||||
|
|
||||||
fun isGroupSearchable(group: Group, omitBackup: Boolean): Boolean {
|
fun isGroupSearchable(group: Group, omitBackup: Boolean): Boolean {
|
||||||
return mDatabaseKDB?.isGroupSearchable(group.groupKDB, omitBackup) ?:
|
return mDatabaseKDB?.isGroupSearchable(group.groupKDB, omitBackup) ?:
|
||||||
mDatabaseKDBX?.isGroupSearchable(group.groupKDBX, omitBackup) ?:
|
mDatabaseKDBX?.isGroupSearchable(group.groupKDBX, omitBackup) ?:
|
||||||
@@ -531,7 +573,7 @@ class Database {
|
|||||||
this.fileUri = uri
|
this.fileUri = uri
|
||||||
}
|
}
|
||||||
|
|
||||||
fun closeAndClear(filesDirectory: File? = null) {
|
fun clear(filesDirectory: File? = null) {
|
||||||
drawFactory.clearCache()
|
drawFactory.clearCache()
|
||||||
// Delete the cache of the database if present
|
// Delete the cache of the database if present
|
||||||
mDatabaseKDB?.clearCache()
|
mDatabaseKDB?.clearCache()
|
||||||
@@ -544,7 +586,10 @@ class Database {
|
|||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e(TAG, "Unable to clear the directory cache.", e)
|
Log.e(TAG, "Unable to clear the directory cache.", e)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clearAndClose(filesDirectory: File? = null) {
|
||||||
|
clear(filesDirectory)
|
||||||
this.mDatabaseKDB = null
|
this.mDatabaseKDB = null
|
||||||
this.mDatabaseKDBX = null
|
this.mDatabaseKDBX = null
|
||||||
this.fileUri = null
|
this.fileUri = null
|
||||||
|
|||||||
@@ -41,6 +41,13 @@ abstract class DatabaseInput<PwDb : DatabaseVersioned<*, *, *, *>>
|
|||||||
abstract fun openDatabase(databaseInputStream: InputStream,
|
abstract fun openDatabase(databaseInputStream: InputStream,
|
||||||
password: String?,
|
password: String?,
|
||||||
keyInputStream: InputStream?,
|
keyInputStream: InputStream?,
|
||||||
|
fixDuplicateUUID: Boolean,
|
||||||
progressTaskUpdater: ProgressTaskUpdater?): PwDb
|
progressTaskUpdater: ProgressTaskUpdater?): PwDb
|
||||||
|
|
||||||
|
|
||||||
|
@Throws(LoadDatabaseException::class)
|
||||||
|
abstract fun openDatabase(databaseInputStream: InputStream,
|
||||||
|
masterKey: ByteArray,
|
||||||
|
fixDuplicateUUID: Boolean,
|
||||||
|
progressTaskUpdater: ProgressTaskUpdater?): PwDb
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,8 +45,7 @@ import javax.crypto.spec.SecretKeySpec
|
|||||||
/**
|
/**
|
||||||
* Load a KDB database file.
|
* Load a KDB database file.
|
||||||
*/
|
*/
|
||||||
class DatabaseInputKDB(cacheDirectory: File,
|
class DatabaseInputKDB(cacheDirectory: File)
|
||||||
private val fixDuplicateUUID: Boolean = false)
|
|
||||||
: DatabaseInput<DatabaseKDB>(cacheDirectory) {
|
: DatabaseInput<DatabaseKDB>(cacheDirectory) {
|
||||||
|
|
||||||
private lateinit var mDatabaseToOpen: DatabaseKDB
|
private lateinit var mDatabaseToOpen: DatabaseKDB
|
||||||
@@ -55,7 +54,28 @@ class DatabaseInputKDB(cacheDirectory: File,
|
|||||||
override fun openDatabase(databaseInputStream: InputStream,
|
override fun openDatabase(databaseInputStream: InputStream,
|
||||||
password: String?,
|
password: String?,
|
||||||
keyInputStream: InputStream?,
|
keyInputStream: InputStream?,
|
||||||
|
fixDuplicateUUID: Boolean,
|
||||||
progressTaskUpdater: ProgressTaskUpdater?): DatabaseKDB {
|
progressTaskUpdater: ProgressTaskUpdater?): DatabaseKDB {
|
||||||
|
return openDatabase(databaseInputStream, fixDuplicateUUID, progressTaskUpdater) {
|
||||||
|
mDatabaseToOpen.retrieveMasterKey(password, keyInputStream)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(LoadDatabaseException::class)
|
||||||
|
override fun openDatabase(databaseInputStream: InputStream,
|
||||||
|
masterKey: ByteArray,
|
||||||
|
fixDuplicateUUID: Boolean,
|
||||||
|
progressTaskUpdater: ProgressTaskUpdater?): DatabaseKDB {
|
||||||
|
return openDatabase(databaseInputStream, fixDuplicateUUID, progressTaskUpdater) {
|
||||||
|
mDatabaseToOpen.masterKey = masterKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(LoadDatabaseException::class)
|
||||||
|
private fun openDatabase(databaseInputStream: InputStream,
|
||||||
|
fixDuplicateUUID: Boolean,
|
||||||
|
progressTaskUpdater: ProgressTaskUpdater?,
|
||||||
|
assignMasterKey: (() -> Unit)? = null): DatabaseKDB {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Load entire file, most of it's encrypted.
|
// Load entire file, most of it's encrypted.
|
||||||
@@ -84,7 +104,7 @@ class DatabaseInputKDB(cacheDirectory: File,
|
|||||||
mDatabaseToOpen = DatabaseKDB()
|
mDatabaseToOpen = DatabaseKDB()
|
||||||
|
|
||||||
mDatabaseToOpen.changeDuplicateId = fixDuplicateUUID
|
mDatabaseToOpen.changeDuplicateId = fixDuplicateUUID
|
||||||
mDatabaseToOpen.retrieveMasterKey(password, keyInputStream)
|
assignMasterKey?.invoke()
|
||||||
|
|
||||||
// Select algorithm
|
// Select algorithm
|
||||||
when {
|
when {
|
||||||
|
|||||||
@@ -63,8 +63,7 @@ import javax.crypto.Cipher
|
|||||||
import javax.crypto.CipherInputStream
|
import javax.crypto.CipherInputStream
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
class DatabaseInputKDBX(cacheDirectory: File,
|
class DatabaseInputKDBX(cacheDirectory: File)
|
||||||
private val fixDuplicateUUID: Boolean = false)
|
|
||||||
: DatabaseInput<DatabaseKDBX>(cacheDirectory) {
|
: DatabaseInput<DatabaseKDBX>(cacheDirectory) {
|
||||||
|
|
||||||
private var randomStream: StreamCipher? = null
|
private var randomStream: StreamCipher? = null
|
||||||
@@ -98,12 +97,30 @@ class DatabaseInputKDBX(cacheDirectory: File,
|
|||||||
override fun openDatabase(databaseInputStream: InputStream,
|
override fun openDatabase(databaseInputStream: InputStream,
|
||||||
password: String?,
|
password: String?,
|
||||||
keyInputStream: InputStream?,
|
keyInputStream: InputStream?,
|
||||||
|
fixDuplicateUUID: Boolean,
|
||||||
progressTaskUpdater: ProgressTaskUpdater?): DatabaseKDBX {
|
progressTaskUpdater: ProgressTaskUpdater?): DatabaseKDBX {
|
||||||
|
return openDatabase(databaseInputStream, fixDuplicateUUID, progressTaskUpdater) { header ->
|
||||||
|
mDatabase.retrieveMasterKey(password, keyInputStream)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(LoadDatabaseException::class)
|
||||||
|
override fun openDatabase(databaseInputStream: InputStream,
|
||||||
|
masterKey: ByteArray,
|
||||||
|
fixDuplicateUUID: Boolean,
|
||||||
|
progressTaskUpdater: ProgressTaskUpdater?): DatabaseKDBX {
|
||||||
|
return openDatabase(databaseInputStream, fixDuplicateUUID, progressTaskUpdater) {
|
||||||
|
mDatabase.masterKey = masterKey
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(LoadDatabaseException::class)
|
||||||
|
private fun openDatabase(databaseInputStream: InputStream,
|
||||||
|
fixDuplicateUUID: Boolean,
|
||||||
|
progressTaskUpdater: ProgressTaskUpdater?,
|
||||||
|
assignMasterKey: ((header: DatabaseHeaderKDBX) -> Unit)? = null): DatabaseKDBX {
|
||||||
try {
|
try {
|
||||||
// TODO performance
|
|
||||||
progressTaskUpdater?.updateMessage(R.string.retrieving_db_key)
|
progressTaskUpdater?.updateMessage(R.string.retrieving_db_key)
|
||||||
|
|
||||||
mDatabase = DatabaseKDBX()
|
mDatabase = DatabaseKDBX()
|
||||||
|
|
||||||
mDatabase.changeDuplicateId = fixDuplicateUUID
|
mDatabase.changeDuplicateId = fixDuplicateUUID
|
||||||
@@ -116,9 +133,8 @@ class DatabaseInputKDBX(cacheDirectory: File,
|
|||||||
hashOfHeader = headerAndHash.hash
|
hashOfHeader = headerAndHash.hash
|
||||||
val pbHeader = headerAndHash.header
|
val pbHeader = headerAndHash.header
|
||||||
|
|
||||||
mDatabase.retrieveMasterKey(password, keyInputStream)
|
assignMasterKey?.invoke(header)
|
||||||
mDatabase.makeFinalKey(header.masterSeed)
|
mDatabase.makeFinalKey(header.masterSeed)
|
||||||
// TODO performance
|
|
||||||
|
|
||||||
progressTaskUpdater?.updateMessage(R.string.decrypting_db)
|
progressTaskUpdater?.updateMessage(R.string.decrypting_db)
|
||||||
val engine: CipherEngine
|
val engine: CipherEngine
|
||||||
|
|||||||
@@ -180,6 +180,7 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
|||||||
val actionRunnable: ActionRunnable? = when (intentAction) {
|
val actionRunnable: ActionRunnable? = when (intentAction) {
|
||||||
ACTION_DATABASE_CREATE_TASK -> buildDatabaseCreateActionTask(intent)
|
ACTION_DATABASE_CREATE_TASK -> buildDatabaseCreateActionTask(intent)
|
||||||
ACTION_DATABASE_LOAD_TASK -> buildDatabaseLoadActionTask(intent)
|
ACTION_DATABASE_LOAD_TASK -> buildDatabaseLoadActionTask(intent)
|
||||||
|
ACTION_DATABASE_RELOAD_TASK -> buildDatabaseReloadActionTask(intent)
|
||||||
ACTION_DATABASE_ASSIGN_PASSWORD_TASK -> buildDatabaseAssignPasswordActionTask(intent)
|
ACTION_DATABASE_ASSIGN_PASSWORD_TASK -> buildDatabaseAssignPasswordActionTask(intent)
|
||||||
ACTION_DATABASE_CREATE_GROUP_TASK -> buildDatabaseCreateGroupActionTask(intent)
|
ACTION_DATABASE_CREATE_GROUP_TASK -> buildDatabaseCreateGroupActionTask(intent)
|
||||||
ACTION_DATABASE_UPDATE_GROUP_TASK -> buildDatabaseUpdateGroupActionTask(intent)
|
ACTION_DATABASE_UPDATE_GROUP_TASK -> buildDatabaseUpdateGroupActionTask(intent)
|
||||||
@@ -258,7 +259,9 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
|||||||
}
|
}
|
||||||
|
|
||||||
return when (intentAction) {
|
return when (intentAction) {
|
||||||
ACTION_DATABASE_LOAD_TASK, null -> {
|
ACTION_DATABASE_LOAD_TASK,
|
||||||
|
ACTION_DATABASE_RELOAD_TASK,
|
||||||
|
null -> {
|
||||||
START_STICKY
|
START_STICKY
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
@@ -292,7 +295,8 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
|||||||
else -> {
|
else -> {
|
||||||
when (intentAction) {
|
when (intentAction) {
|
||||||
ACTION_DATABASE_CREATE_TASK -> R.string.creating_database
|
ACTION_DATABASE_CREATE_TASK -> R.string.creating_database
|
||||||
ACTION_DATABASE_LOAD_TASK -> R.string.loading_database
|
ACTION_DATABASE_LOAD_TASK,
|
||||||
|
ACTION_DATABASE_RELOAD_TASK -> R.string.loading_database
|
||||||
ACTION_DATABASE_SAVE -> R.string.saving_database
|
ACTION_DATABASE_SAVE -> R.string.saving_database
|
||||||
else -> {
|
else -> {
|
||||||
R.string.command_execution
|
R.string.command_execution
|
||||||
@@ -302,13 +306,15 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
|||||||
}
|
}
|
||||||
|
|
||||||
mMessageId = when (intentAction) {
|
mMessageId = when (intentAction) {
|
||||||
ACTION_DATABASE_LOAD_TASK -> null
|
ACTION_DATABASE_LOAD_TASK,
|
||||||
|
ACTION_DATABASE_RELOAD_TASK -> null
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
mWarningId =
|
mWarningId =
|
||||||
if (!saveAction
|
if (!saveAction
|
||||||
|| intentAction == ACTION_DATABASE_LOAD_TASK)
|
|| intentAction == ACTION_DATABASE_LOAD_TASK
|
||||||
|
|| intentAction == ACTION_DATABASE_RELOAD_TASK)
|
||||||
null
|
null
|
||||||
else
|
else
|
||||||
R.string.do_not_kill_app
|
R.string.do_not_kill_app
|
||||||
@@ -509,6 +515,23 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun buildDatabaseReloadActionTask(intent: Intent): ActionRunnable? {
|
||||||
|
|
||||||
|
return if (intent.hasExtra(FIX_DUPLICATE_UUID_KEY)) {
|
||||||
|
ReloadDatabaseRunnable(
|
||||||
|
this,
|
||||||
|
mDatabase,
|
||||||
|
intent.getBooleanExtra(FIX_DUPLICATE_UUID_KEY, false),
|
||||||
|
this
|
||||||
|
) { result ->
|
||||||
|
// No need to add each info to reload database
|
||||||
|
result.data = Bundle()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun buildDatabaseAssignPasswordActionTask(intent: Intent): ActionRunnable? {
|
private fun buildDatabaseAssignPasswordActionTask(intent: Intent): ActionRunnable? {
|
||||||
return if (intent.hasExtra(DATABASE_URI_KEY)
|
return if (intent.hasExtra(DATABASE_URI_KEY)
|
||||||
&& intent.hasExtra(MASTER_PASSWORD_CHECKED_KEY)
|
&& intent.hasExtra(MASTER_PASSWORD_CHECKED_KEY)
|
||||||
@@ -814,6 +837,7 @@ open class DatabaseTaskNotificationService : LockNotificationService(), Progress
|
|||||||
|
|
||||||
const val ACTION_DATABASE_CREATE_TASK = "ACTION_DATABASE_CREATE_TASK"
|
const val ACTION_DATABASE_CREATE_TASK = "ACTION_DATABASE_CREATE_TASK"
|
||||||
const val ACTION_DATABASE_LOAD_TASK = "ACTION_DATABASE_LOAD_TASK"
|
const val ACTION_DATABASE_LOAD_TASK = "ACTION_DATABASE_LOAD_TASK"
|
||||||
|
const val ACTION_DATABASE_RELOAD_TASK = "ACTION_DATABASE_RELOAD_TASK"
|
||||||
const val ACTION_DATABASE_ASSIGN_PASSWORD_TASK = "ACTION_DATABASE_ASSIGN_PASSWORD_TASK"
|
const val ACTION_DATABASE_ASSIGN_PASSWORD_TASK = "ACTION_DATABASE_ASSIGN_PASSWORD_TASK"
|
||||||
const val ACTION_DATABASE_CREATE_GROUP_TASK = "ACTION_DATABASE_CREATE_GROUP_TASK"
|
const val ACTION_DATABASE_CREATE_GROUP_TASK = "ACTION_DATABASE_CREATE_GROUP_TASK"
|
||||||
const val ACTION_DATABASE_UPDATE_GROUP_TASK = "ACTION_DATABASE_UPDATE_GROUP_TASK"
|
const val ACTION_DATABASE_UPDATE_GROUP_TASK = "ACTION_DATABASE_UPDATE_GROUP_TASK"
|
||||||
|
|||||||
@@ -552,6 +552,10 @@ class NestedDatabaseSettingsFragment : NestedSettingsFragment() {
|
|||||||
settingActivity?.mProgressDatabaseTaskProvider?.startDatabaseSave(!mDatabaseReadOnly)
|
settingActivity?.mProgressDatabaseTaskProvider?.startDatabaseSave(!mDatabaseReadOnly)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
R.id.menu_reload_database -> {
|
||||||
|
settingActivity?.mProgressDatabaseTaskProvider?.startDatabaseReload(false)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
// Check the time lock before launching settings
|
// Check the time lock before launching settings
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import com.kunzisoft.keepass.activities.helpers.ReadOnlyHelper
|
|||||||
import com.kunzisoft.keepass.activities.lock.LockingActivity
|
import com.kunzisoft.keepass.activities.lock.LockingActivity
|
||||||
import com.kunzisoft.keepass.activities.lock.resetAppTimeoutWhenViewFocusedOrChanged
|
import com.kunzisoft.keepass.activities.lock.resetAppTimeoutWhenViewFocusedOrChanged
|
||||||
import com.kunzisoft.keepass.database.element.Database
|
import com.kunzisoft.keepass.database.element.Database
|
||||||
|
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService
|
||||||
import com.kunzisoft.keepass.timeout.TimeoutHelper
|
import com.kunzisoft.keepass.timeout.TimeoutHelper
|
||||||
import com.kunzisoft.keepass.view.showActionError
|
import com.kunzisoft.keepass.view.showActionError
|
||||||
|
|
||||||
@@ -95,12 +96,19 @@ open class SettingsActivity
|
|||||||
backupManager = BackupManager(this)
|
backupManager = BackupManager(this)
|
||||||
|
|
||||||
mProgressDatabaseTaskProvider?.onActionFinish = { actionTask, result ->
|
mProgressDatabaseTaskProvider?.onActionFinish = { actionTask, result ->
|
||||||
// Call result in fragment
|
when (actionTask) {
|
||||||
(supportFragmentManager
|
DatabaseTaskNotificationService.ACTION_DATABASE_RELOAD_TASK -> {
|
||||||
.findFragmentByTag(TAG_NESTED) as NestedSettingsFragment?)
|
// Close the current activity
|
||||||
?.onProgressDialogThreadResult(actionTask, result)
|
finish()
|
||||||
|
}
|
||||||
coordinatorLayout?.showActionError(result)
|
else -> {
|
||||||
|
// Call result in fragment
|
||||||
|
(supportFragmentManager
|
||||||
|
.findFragmentByTag(TAG_NESTED) as NestedSettingsFragment?)
|
||||||
|
?.onProgressDialogThreadResult(actionTask, result)
|
||||||
|
coordinatorLayout?.showActionError(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -138,5 +138,5 @@ fun Context.closeDatabase() {
|
|||||||
cancelAll()
|
cancelAll()
|
||||||
}
|
}
|
||||||
// Clear data
|
// Clear data
|
||||||
Database.getInstance().closeAndClear(UriUtil.getBinaryDir(this))
|
Database.getInstance().clearAndClose(UriUtil.getBinaryDir(this))
|
||||||
}
|
}
|
||||||
7
app/src/main/res/drawable/ic_reload_white_24dp.xml
Normal file
7
app/src/main/res/drawable/ic_reload_white_24dp.xml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:height="24dp"
|
||||||
|
android:width="24dp"
|
||||||
|
android:viewportHeight="24"
|
||||||
|
android:viewportWidth="24" >
|
||||||
|
<path android:fillColor="#FFFFFF" android:pathData="M12,4L12,1L8,5l4,4L12,6c3.31,0 6,2.69 6,6 0,1.01 -0.25,1.97 -0.7,2.8l1.46,1.46C19.54,15.03 20,13.57 20,12c0,-4.42 -3.58,-8 -8,-8zM12,18c-3.31,0 -6,-2.69 -6,-6 0,-1.01 0.25,-1.97 0.7,-2.8L5.24,7.74C4.46,8.97 4,10.43 4,12c0,4.42 3.58,8 8,8v3l4,-4 -4,-4v3z"/>
|
||||||
|
</vector>
|
||||||
@@ -22,6 +22,6 @@
|
|||||||
<item android:id="@+id/menu_contribute"
|
<item android:id="@+id/menu_contribute"
|
||||||
android:icon="@drawable/ic_heart_white_24dp"
|
android:icon="@drawable/ic_heart_white_24dp"
|
||||||
android:title="@string/contribute"
|
android:title="@string/contribute"
|
||||||
android:orderInCategory="95"
|
android:orderInCategory="99"
|
||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="ifRoom" />
|
||||||
</menu>
|
</menu>
|
||||||
@@ -24,4 +24,9 @@
|
|||||||
android:title="@string/menu_save_database"
|
android:title="@string/menu_save_database"
|
||||||
android:orderInCategory="95"
|
android:orderInCategory="95"
|
||||||
app:showAsAction="ifRoom" />
|
app:showAsAction="ifRoom" />
|
||||||
|
<item android:id="@+id/menu_reload_database"
|
||||||
|
android:icon="@drawable/ic_reload_white_24dp"
|
||||||
|
android:title="@string/menu_reload_database"
|
||||||
|
android:orderInCategory="96"
|
||||||
|
app:showAsAction="ifRoom" />
|
||||||
</menu>
|
</menu>
|
||||||
@@ -185,6 +185,7 @@
|
|||||||
<string name="menu_hide_password">Hide password</string>
|
<string name="menu_hide_password">Hide password</string>
|
||||||
<string name="menu_lock">Lock database</string>
|
<string name="menu_lock">Lock database</string>
|
||||||
<string name="menu_save_database">Save database</string>
|
<string name="menu_save_database">Save database</string>
|
||||||
|
<string name="menu_reload_database">Reload database</string>
|
||||||
<string name="menu_open">Open</string>
|
<string name="menu_open">Open</string>
|
||||||
<string name="menu_search">Search</string>
|
<string name="menu_search">Search</string>
|
||||||
<string name="menu_showpass">Show password</string>
|
<string name="menu_showpass">Show password</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user