mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
fix: Separate Main credential, remove ContentProvider from Database
This commit is contained in:
@@ -54,7 +54,7 @@ import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
|
||||
import com.kunzisoft.keepass.autofill.AutofillComponent
|
||||
import com.kunzisoft.keepass.autofill.AutofillHelper
|
||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||
import com.kunzisoft.keepass.database.element.MainCredential
|
||||
import com.kunzisoft.keepass.database.MainCredential
|
||||
import com.kunzisoft.keepass.education.FileDatabaseSelectActivityEducation
|
||||
import com.kunzisoft.keepass.hardware.HardwareKey
|
||||
import com.kunzisoft.keepass.model.RegisterInfo
|
||||
|
||||
@@ -75,10 +75,10 @@ import com.kunzisoft.keepass.adapters.BreadcrumbAdapter
|
||||
import com.kunzisoft.keepass.autofill.AutofillComponent
|
||||
import com.kunzisoft.keepass.autofill.AutofillHelper
|
||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||
import com.kunzisoft.keepass.database.MainCredential
|
||||
import com.kunzisoft.keepass.database.element.DateInstant
|
||||
import com.kunzisoft.keepass.database.element.Entry
|
||||
import com.kunzisoft.keepass.database.element.Group
|
||||
import com.kunzisoft.keepass.database.element.MainCredential
|
||||
import com.kunzisoft.keepass.database.element.SortNodeEnum
|
||||
import com.kunzisoft.keepass.database.element.node.Node
|
||||
import com.kunzisoft.keepass.database.element.node.NodeId
|
||||
|
||||
@@ -56,7 +56,7 @@ import com.kunzisoft.keepass.autofill.AutofillHelper
|
||||
import com.kunzisoft.keepass.biometric.AdvancedUnlockFragment
|
||||
import com.kunzisoft.keepass.biometric.AdvancedUnlockManager
|
||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||
import com.kunzisoft.keepass.database.element.MainCredential
|
||||
import com.kunzisoft.keepass.database.MainCredential
|
||||
import com.kunzisoft.keepass.database.exception.DuplicateUuidDatabaseException
|
||||
import com.kunzisoft.keepass.database.exception.FileNotFoundDatabaseException
|
||||
import com.kunzisoft.keepass.education.PasswordActivityEducation
|
||||
|
||||
@@ -27,7 +27,7 @@ import android.widget.TextView
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper
|
||||
import com.kunzisoft.keepass.database.element.MainCredential
|
||||
import com.kunzisoft.keepass.database.MainCredential
|
||||
import com.kunzisoft.keepass.utils.UriUtil.getDocumentFile
|
||||
import com.kunzisoft.keepass.view.MainCredentialView
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import android.os.Bundle
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.database.element.MainCredential
|
||||
import com.kunzisoft.keepass.database.MainCredential
|
||||
|
||||
class PasswordEncodingDialogFragment : DialogFragment() {
|
||||
|
||||
@@ -78,8 +78,10 @@ class PasswordEncodingDialogFragment : DialogFragment() {
|
||||
private const val DATABASE_URI_KEY = "DATABASE_URI_KEY"
|
||||
private const val MAIN_CREDENTIAL = "MAIN_CREDENTIAL"
|
||||
|
||||
fun getInstance(databaseUri: Uri,
|
||||
mainCredential: MainCredential): SortDialogFragment {
|
||||
fun getInstance(
|
||||
databaseUri: Uri,
|
||||
mainCredential: MainCredential
|
||||
): SortDialogFragment {
|
||||
val fragment = SortDialogFragment()
|
||||
fragment.arguments = Bundle().apply {
|
||||
putParcelable(DATABASE_URI_KEY, databaseUri)
|
||||
|
||||
@@ -35,7 +35,7 @@ import com.google.android.material.textfield.TextInputLayout
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper
|
||||
import com.kunzisoft.keepass.activities.helpers.setOpenDocumentClickListener
|
||||
import com.kunzisoft.keepass.database.element.MainCredential
|
||||
import com.kunzisoft.keepass.database.MainCredential
|
||||
import com.kunzisoft.keepass.hardware.HardwareKey
|
||||
import com.kunzisoft.keepass.hardware.HardwareKeyActivity
|
||||
import com.kunzisoft.keepass.password.PasswordEntropy
|
||||
|
||||
@@ -5,8 +5,8 @@ import android.os.Bundle
|
||||
import androidx.activity.viewModels
|
||||
import com.kunzisoft.keepass.activities.stylish.StylishActivity
|
||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||
import com.kunzisoft.keepass.database.MainCredential
|
||||
import com.kunzisoft.keepass.database.action.DatabaseTaskProvider
|
||||
import com.kunzisoft.keepass.database.element.MainCredential
|
||||
import com.kunzisoft.keepass.model.CipherEncryptDatabase
|
||||
import com.kunzisoft.keepass.tasks.ActionRunnable
|
||||
import com.kunzisoft.keepass.utils.UriUtil.getBinaryDir
|
||||
|
||||
@@ -37,10 +37,10 @@ import com.kunzisoft.keepass.activities.dialogs.PasswordEncodingDialogFragment
|
||||
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
|
||||
import com.kunzisoft.keepass.activities.helpers.SpecialMode
|
||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||
import com.kunzisoft.keepass.database.MainCredential
|
||||
import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.database.element.Entry
|
||||
import com.kunzisoft.keepass.database.element.Group
|
||||
import com.kunzisoft.keepass.database.element.MainCredential
|
||||
import com.kunzisoft.keepass.database.element.node.Node
|
||||
import com.kunzisoft.keepass.database.element.node.NodeId
|
||||
import com.kunzisoft.keepass.model.GroupInfo
|
||||
@@ -251,7 +251,7 @@ abstract class DatabaseLockActivity : DatabaseModeActivity(),
|
||||
mDatabase?.let { database ->
|
||||
database.fileUri?.let { databaseUri ->
|
||||
// Show the progress dialog now or after dialog confirmation
|
||||
if (database.validatePasswordEncoding(mainCredential)) {
|
||||
if (database.isValidCredential(mainCredential.toMasterCredential(contentResolver))) {
|
||||
assignDatabasePassword(databaseUri, mainCredential)
|
||||
} else {
|
||||
PasswordEncodingDialogFragment.getInstance(databaseUri, mainCredential)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.kunzisoft.keepass.database
|
||||
|
||||
import android.net.Uri
|
||||
import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.database.element.icon.IconImageCustom
|
||||
import com.kunzisoft.keepass.icons.IconDrawableFactory
|
||||
@@ -8,6 +9,8 @@ import java.io.File
|
||||
|
||||
class ContextualDatabase: Database() {
|
||||
|
||||
var fileUri: Uri? = null
|
||||
|
||||
val iconDrawableFactory = IconDrawableFactory(
|
||||
retrieveBinaryCache = { binaryCache },
|
||||
retrieveCustomIconBinary = { iconId -> getBinaryForCustomIcon(iconId) }
|
||||
@@ -23,6 +26,11 @@ class ContextualDatabase: Database() {
|
||||
super.clearIndexesAndBinaries(filesDirectory)
|
||||
}
|
||||
|
||||
override fun clearAndClose(filesDirectory: File?) {
|
||||
super.clearAndClose(filesDirectory)
|
||||
this.fileUri = null
|
||||
}
|
||||
|
||||
companion object : SingletonHolder<ContextualDatabase>(::ContextualDatabase) {
|
||||
private val TAG = ContextualDatabase::class.java.name
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
|
||||
import android.content.ContentResolver
|
||||
import android.net.Uri
|
||||
import android.os.Parcel
|
||||
import android.os.Parcelable
|
||||
import com.kunzisoft.keepass.database.element.MasterCredential
|
||||
import com.kunzisoft.keepass.hardware.HardwareKey
|
||||
import com.kunzisoft.keepass.utils.UriHelper.getUriInputStream
|
||||
import com.kunzisoft.keepass.utils.readEnum
|
||||
import com.kunzisoft.keepass.utils.writeEnum
|
||||
|
||||
data class MainCredential(var password: String? = null,
|
||||
var keyFileUri: Uri? = null,
|
||||
var hardwareKey: HardwareKey? = null): Parcelable {
|
||||
|
||||
constructor(parcel: Parcel) : this() {
|
||||
password = parcel.readString()
|
||||
keyFileUri = parcel.readParcelable(Uri::class.java.classLoader)
|
||||
hardwareKey = parcel.readEnum<HardwareKey>()
|
||||
}
|
||||
|
||||
override fun writeToParcel(parcel: Parcel, flags: Int) {
|
||||
parcel.writeString(password)
|
||||
parcel.writeParcelable(keyFileUri, flags)
|
||||
parcel.writeEnum(hardwareKey)
|
||||
}
|
||||
|
||||
override fun describeContents(): Int {
|
||||
return 0
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as MainCredential
|
||||
|
||||
if (password != other.password) return false
|
||||
if (keyFileUri != other.keyFileUri) return false
|
||||
if (hardwareKey != other.hardwareKey) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = password?.hashCode() ?: 0
|
||||
result = 31 * result + (keyFileUri?.hashCode() ?: 0)
|
||||
result = 31 * result + (hardwareKey?.hashCode() ?: 0)
|
||||
return result
|
||||
}
|
||||
|
||||
fun toMasterCredential(contentResolver: ContentResolver): MasterCredential {
|
||||
return MasterCredential(
|
||||
this.password,
|
||||
this.keyFileUri?.let {
|
||||
getKeyFileData(contentResolver, it)
|
||||
},
|
||||
this.hardwareKey
|
||||
)
|
||||
}
|
||||
|
||||
private fun getKeyFileData(contentResolver: ContentResolver,
|
||||
keyFileUri: Uri): ByteArray? {
|
||||
contentResolver.getUriInputStream(keyFileUri)?.use { keyFileInputStream ->
|
||||
return keyFileInputStream.readBytes()
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
companion object CREATOR : Parcelable.Creator<MainCredential> {
|
||||
override fun createFromParcel(parcel: Parcel): MainCredential {
|
||||
return MainCredential(parcel)
|
||||
}
|
||||
|
||||
override fun newArray(size: Int): Array<MainCredential?> {
|
||||
return arrayOfNulls(size)
|
||||
}
|
||||
|
||||
private val TAG = MainCredential::class.java.simpleName
|
||||
}
|
||||
}
|
||||
@@ -24,7 +24,7 @@ import android.net.Uri
|
||||
import com.kunzisoft.keepass.app.database.CipherDatabaseAction
|
||||
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
|
||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||
import com.kunzisoft.keepass.database.element.MainCredential
|
||||
import com.kunzisoft.keepass.database.MainCredential
|
||||
import com.kunzisoft.keepass.hardware.HardwareKey
|
||||
|
||||
open class AssignMainCredentialInDatabaseRunnable (
|
||||
|
||||
@@ -24,7 +24,7 @@ import android.net.Uri
|
||||
import android.util.Log
|
||||
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
|
||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||
import com.kunzisoft.keepass.database.element.MainCredential
|
||||
import com.kunzisoft.keepass.database.MainCredential
|
||||
import com.kunzisoft.keepass.hardware.HardwareKey
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import com.kunzisoft.keepass.utils.UriUtil.getBinaryDir
|
||||
@@ -45,7 +45,8 @@ class CreateDatabaseRunnable(
|
||||
try {
|
||||
// Create new database record
|
||||
mDatabase.apply {
|
||||
createData(mDatabaseUri, databaseName, rootName, templateGroupName)
|
||||
this.fileUri = mDatabaseUri
|
||||
createData(databaseName, rootName, templateGroupName)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
mDatabase.clearAndClose(context.getBinaryDir())
|
||||
|
||||
@@ -40,11 +40,11 @@ import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.dialogs.DatabaseChangedDialogFragment
|
||||
import com.kunzisoft.keepass.activities.dialogs.DatabaseChangedDialogFragment.Companion.DATABASE_CHANGED_DIALOG_TAG
|
||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||
import com.kunzisoft.keepass.database.MainCredential
|
||||
import com.kunzisoft.keepass.database.crypto.EncryptionAlgorithm
|
||||
import com.kunzisoft.keepass.database.crypto.kdf.KdfEngine
|
||||
import com.kunzisoft.keepass.database.element.Entry
|
||||
import com.kunzisoft.keepass.database.element.Group
|
||||
import com.kunzisoft.keepass.database.element.MainCredential
|
||||
import com.kunzisoft.keepass.database.element.database.CompressionAlgorithm
|
||||
import com.kunzisoft.keepass.database.element.node.Node
|
||||
import com.kunzisoft.keepass.database.element.node.NodeId
|
||||
|
||||
@@ -24,14 +24,16 @@ import android.net.Uri
|
||||
import com.kunzisoft.keepass.app.database.CipherDatabaseAction
|
||||
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
|
||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||
import com.kunzisoft.keepass.database.element.MainCredential
|
||||
import com.kunzisoft.keepass.database.MainCredential
|
||||
import com.kunzisoft.keepass.database.element.binary.BinaryData
|
||||
import com.kunzisoft.keepass.database.exception.DatabaseInputException
|
||||
import com.kunzisoft.keepass.database.exception.UnknownDatabaseLocationException
|
||||
import com.kunzisoft.keepass.hardware.HardwareKey
|
||||
import com.kunzisoft.keepass.model.CipherEncryptDatabase
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import com.kunzisoft.keepass.tasks.ActionRunnable
|
||||
import com.kunzisoft.keepass.tasks.ProgressTaskUpdater
|
||||
import com.kunzisoft.keepass.utils.UriHelper.getUriInputStream
|
||||
import com.kunzisoft.keepass.utils.UriUtil.getBinaryDir
|
||||
|
||||
class LoadDatabaseRunnable(
|
||||
@@ -56,10 +58,13 @@ class LoadDatabaseRunnable(
|
||||
|
||||
override fun onActionRun() {
|
||||
try {
|
||||
val contentResolver = context.contentResolver
|
||||
// Save database URI
|
||||
mDatabase.fileUri = mDatabaseUri
|
||||
mDatabase.loadData(
|
||||
context.contentResolver,
|
||||
mDatabaseUri,
|
||||
mMainCredential,
|
||||
contentResolver.getUriInputStream(mDatabaseUri)
|
||||
?: throw UnknownDatabaseLocationException(),
|
||||
mMainCredential.toMasterCredential(contentResolver),
|
||||
mChallengeResponseRetriever,
|
||||
mReadonly,
|
||||
binaryDir,
|
||||
|
||||
@@ -22,12 +22,14 @@ package com.kunzisoft.keepass.database.action
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||
import com.kunzisoft.keepass.database.element.MainCredential
|
||||
import com.kunzisoft.keepass.database.MainCredential
|
||||
import com.kunzisoft.keepass.database.element.binary.BinaryData
|
||||
import com.kunzisoft.keepass.database.exception.DatabaseException
|
||||
import com.kunzisoft.keepass.database.exception.UnknownDatabaseLocationException
|
||||
import com.kunzisoft.keepass.hardware.HardwareKey
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import com.kunzisoft.keepass.tasks.ProgressTaskUpdater
|
||||
import com.kunzisoft.keepass.utils.UriHelper.getUriInputStream
|
||||
|
||||
class MergeDatabaseRunnable(
|
||||
context: Context,
|
||||
@@ -48,10 +50,12 @@ class MergeDatabaseRunnable(
|
||||
|
||||
override fun onActionRun() {
|
||||
try {
|
||||
val contentResolver = context.contentResolver
|
||||
database.mergeData(
|
||||
context.contentResolver,
|
||||
mDatabaseToMergeUri,
|
||||
mDatabaseToMergeMainCredential,
|
||||
context.contentResolver.getUriInputStream(
|
||||
mDatabaseToMergeUri ?: database.fileUri
|
||||
) ?: throw UnknownDatabaseLocationException(),
|
||||
mDatabaseToMergeMainCredential?.toMasterCredential(contentResolver),
|
||||
mDatabaseToMergeChallengeResponseRetriever,
|
||||
{ memoryWanted ->
|
||||
BinaryData.canMemoryBeAllocatedInRAM(context, memoryWanted)
|
||||
|
||||
@@ -23,9 +23,11 @@ import android.content.Context
|
||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||
import com.kunzisoft.keepass.database.element.binary.BinaryData
|
||||
import com.kunzisoft.keepass.database.exception.DatabaseException
|
||||
import com.kunzisoft.keepass.database.exception.UnknownDatabaseLocationException
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import com.kunzisoft.keepass.tasks.ActionRunnable
|
||||
import com.kunzisoft.keepass.tasks.ProgressTaskUpdater
|
||||
import com.kunzisoft.keepass.utils.UriHelper.getUriInputStream
|
||||
import com.kunzisoft.keepass.utils.UriUtil.getBinaryDir
|
||||
|
||||
class ReloadDatabaseRunnable(
|
||||
@@ -45,7 +47,9 @@ class ReloadDatabaseRunnable(
|
||||
|
||||
override fun onActionRun() {
|
||||
try {
|
||||
mDatabase.reloadData(context.contentResolver,
|
||||
mDatabase.reloadData(
|
||||
context.contentResolver.getUriInputStream(mDatabase.fileUri)
|
||||
?: throw UnknownDatabaseLocationException(),
|
||||
{ memoryWanted ->
|
||||
BinaryData.canMemoryBeAllocatedInRAM(context, memoryWanted)
|
||||
},
|
||||
|
||||
@@ -22,10 +22,12 @@ package com.kunzisoft.keepass.database.action
|
||||
import android.content.Context
|
||||
import android.net.Uri
|
||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||
import com.kunzisoft.keepass.database.element.MainCredential
|
||||
import com.kunzisoft.keepass.database.MainCredential
|
||||
import com.kunzisoft.keepass.database.exception.DatabaseException
|
||||
import com.kunzisoft.keepass.hardware.HardwareKey
|
||||
import com.kunzisoft.keepass.tasks.ActionRunnable
|
||||
import com.kunzisoft.keepass.utils.UriHelper.getUriOutputStream
|
||||
import java.io.File
|
||||
|
||||
open class SaveDatabaseRunnable(
|
||||
protected var context: Context,
|
||||
@@ -44,11 +46,14 @@ open class SaveDatabaseRunnable(
|
||||
database.checkVersion()
|
||||
if (saveDatabase && result.isSuccess) {
|
||||
try {
|
||||
val contentResolver = context.contentResolver
|
||||
// Build temp database file to avoid file corruption if error
|
||||
database.saveData(
|
||||
context.contentResolver,
|
||||
context.cacheDir,
|
||||
databaseCopyUri,
|
||||
mainCredential,
|
||||
cacheFile = File(context.cacheDir, databaseCopyUri.hashCode().toString()),
|
||||
databaseOutputStream = context.contentResolver
|
||||
.getUriOutputStream(databaseCopyUri ?: database.fileUri),
|
||||
isNewLocation = databaseCopyUri == null,
|
||||
mainCredential?.toMasterCredential(contentResolver),
|
||||
challengeResponseRetriever)
|
||||
} catch (e: DatabaseException) {
|
||||
setError(e)
|
||||
|
||||
@@ -32,6 +32,7 @@ import androidx.media.app.NotificationCompat
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.GroupActivity
|
||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||
import com.kunzisoft.keepass.database.MainCredential
|
||||
import com.kunzisoft.keepass.database.action.*
|
||||
import com.kunzisoft.keepass.database.action.history.DeleteEntryHistoryDatabaseRunnable
|
||||
import com.kunzisoft.keepass.database.action.history.RestoreEntryHistoryDatabaseRunnable
|
||||
@@ -39,7 +40,6 @@ import com.kunzisoft.keepass.database.action.node.*
|
||||
import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.database.element.Entry
|
||||
import com.kunzisoft.keepass.database.element.Group
|
||||
import com.kunzisoft.keepass.database.element.MainCredential
|
||||
import com.kunzisoft.keepass.database.element.database.CompressionAlgorithm
|
||||
import com.kunzisoft.keepass.database.element.node.Node
|
||||
import com.kunzisoft.keepass.database.element.node.NodeId
|
||||
|
||||
@@ -36,7 +36,7 @@ import com.kunzisoft.keepass.activities.dialogs.SetMainCredentialDialogFragment
|
||||
import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper
|
||||
import com.kunzisoft.keepass.activities.legacy.DatabaseLockActivity
|
||||
import com.kunzisoft.keepass.database.ContextualDatabase
|
||||
import com.kunzisoft.keepass.database.element.MainCredential
|
||||
import com.kunzisoft.keepass.database.MainCredential
|
||||
import com.kunzisoft.keepass.tasks.ActionRunnable
|
||||
import com.kunzisoft.keepass.timeout.TimeoutHelper
|
||||
import com.kunzisoft.keepass.view.showActionErrorIfNeeded
|
||||
|
||||
@@ -38,9 +38,9 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper
|
||||
import com.kunzisoft.keepass.activities.helpers.setOpenDocumentClickListener
|
||||
import com.kunzisoft.keepass.model.CredentialStorage
|
||||
import com.kunzisoft.keepass.database.element.MainCredential
|
||||
import com.kunzisoft.keepass.database.MainCredential
|
||||
import com.kunzisoft.keepass.hardware.HardwareKey
|
||||
import com.kunzisoft.keepass.model.CredentialStorage
|
||||
|
||||
class MainCredentialView @JvmOverloads constructor(context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
|
||||
Reference in New Issue
Block a user