Skip to content

Commit

Permalink
Merge branch 'release/2.5beta30'
Browse files Browse the repository at this point in the history
  • Loading branch information
J-Jamet committed Mar 27, 2020
2 parents 9fc5e67 + cb982b3 commit 32d235e
Show file tree
Hide file tree
Showing 18 changed files with 171 additions and 189 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
KeePassDX(2.5beta30)
* Fix Lock after screen off (wait 1.5 seconds)
* Upgrade autofill algorithm
* Fix ANR during file verifications

KeePassDX(2.5beta29)
* Upgrade autofill algorithm
* Delete registered KeyFile after save new credentials
Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ android {
applicationId "com.kunzisoft.keepass"
minSdkVersion 14
targetSdkVersion 29
versionCode = 29
versionName = "2.5beta29"
versionCode = 30
versionName = "2.5beta30"
multiDexEnabled true

testApplicationId = "com.kunzisoft.keepass.tests"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ class EntryEditActivity : LockingActivity(),
AlertDialog.Builder(this)
.setMessage(R.string.discard_changes)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(android.R.string.ok) { _, _ ->
.setPositiveButton(R.string.discard) { _, _ ->
super@EntryEditActivity.onBackPressed()
}.create().show()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import android.view.View
import android.widget.TextView
import androidx.annotation.RequiresApi
import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.SimpleItemAnimator
Expand All @@ -61,6 +62,7 @@ class FileDatabaseSelectActivity : StylishActivity(),
AssignMasterKeyDialogFragment.AssignPasswordDialogListener {

// Views
private var coordinatorLayout: CoordinatorLayout? = null
private var fileListContainer: View? = null
private var createButtonView: View? = null
private var openDatabaseButtonView: View? = null
Expand All @@ -82,6 +84,7 @@ class FileDatabaseSelectActivity : StylishActivity(),
mFileDatabaseHistoryAction = FileDatabaseHistoryAction.getInstance(applicationContext)

setContentView(R.layout.activity_file_selection)
coordinatorLayout = findViewById(R.id.activity_file_selection_coordinator_layout)
fileListContainer = findViewById(R.id.container_file_list)

val toolbar = findViewById<Toolbar>(R.id.toolbar)
Expand Down Expand Up @@ -179,7 +182,9 @@ class FileDatabaseSelectActivity : StylishActivity(),

private fun fileNoFoundAction(e: FileNotFoundException) {
val error = getString(R.string.file_not_found_content)
Snackbar.make(activity_file_selection_coordinator_layout, error, Snackbar.LENGTH_LONG).asError().show()
coordinatorLayout?.let {
Snackbar.make(it, error, Snackbar.LENGTH_LONG).asError().show()
}
Log.e(TAG, error, e)
}

Expand Down Expand Up @@ -278,9 +283,8 @@ class FileDatabaseSelectActivity : StylishActivity(),
// Show only uri accessible
historyList.filter {
if (hideBrokenLocations) {
UriUtil.parse(it.databaseUri)?.let { historyUri ->
UriUtil.isUriAccessible(contentResolver, historyUri)
} ?: false
FileDatabaseInfo(this@FileDatabaseSelectActivity,
it.databaseUri).exists
} else
true
})
Expand Down Expand Up @@ -369,10 +373,13 @@ class FileDatabaseSelectActivity : StylishActivity(),
if (mDatabaseFileUri != null) {
AssignMasterKeyDialogFragment.getInstance(true)
.show(supportFragmentManager, "passwordDialog")
} else {
val error = getString(R.string.error_create_database)
coordinatorLayout?.let {
Snackbar.make(it, error, Snackbar.LENGTH_LONG).asError().show()
}
Log.e(TAG, error)
}
// else {
// TODO Show error
// }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,13 @@ open class PasswordActivity : StylishActivity() {
}

private fun initUriFromIntent() {
mForceReadOnly = !UriUtil.isUriWritable(mDatabaseFileUri)
/*
// "canXrite" doesn't work with Google Drive, don't really know why?
mForceReadOnly = mDatabaseFileUri?.let {
!FileDatabaseInfo(this, it).canWrite
} ?: false
*/
mForceReadOnly = false

// Post init uri with KeyFile if needed
if (mRememberKeyFile && (mDatabaseKeyFileUri == null || mDatabaseKeyFileUri.toString().isEmpty())) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,24 +84,25 @@ class FileDatabaseHistoryAdapter(private val context: Context)
// File path
holder.filePath.text = UriUtil.decode(fileDatabaseInfo.fileUri?.toString())

if (fileDatabaseInfo.dataAccessible()) {
if (fileDatabaseInfo.exists) {
holder.fileInformation.clearColorFilter()
} else {
holder.fileInformation.setColorFilter(Color.RED, PorterDuff.Mode.MULTIPLY)
}

// Modification
if (fileDatabaseInfo.lastModificationAccessible()) {
holder.fileModification.text = fileDatabaseInfo.getModificationString()
fileDatabaseInfo.getModificationString()?.let {
holder.fileModification.text = it
holder.fileModification.visibility = View.VISIBLE
} else {
} ?: run {
holder.fileModification.visibility = View.GONE
}

// Size
if (fileDatabaseInfo.sizeAccessible()) {
holder.fileSize.text = fileDatabaseInfo.getSizeString()
fileDatabaseInfo.getSizeString()?.let {
holder.fileSize.text = it
holder.fileSize.visibility = View.VISIBLE
} else {
} ?: run {
holder.fileSize.visibility = View.GONE
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import java.util.*
internal class StructureParser(private val structure: AssistStructure) {
private var result: Result? = null
private var usernameCandidate: AutofillId? = null
private var lockHint: Boolean = false

fun parse(): Result? {
result = Result()
Expand Down Expand Up @@ -98,15 +97,12 @@ internal class StructureParser(private val structure: AssistStructure) {
Log.d(TAG, "Autofill password hint")
return true
}
it.toLowerCase(Locale.ENGLISH) == "off" -> {
Log.d(TAG, "Autofill OFF hint")
lockHint = true
return false
}
// Ignore autocomplete="off"
// https://developer.mozilla.org/en-US/docs/Web/Security/Securing_your_site/Turning_off_form_autocompletion
it.toLowerCase(Locale.ENGLISH) == "off" ||
it.toLowerCase(Locale.ENGLISH) == "on" -> {
Log.d(TAG, "Autofill ON hint")
if (parseNodeByHtmlAttributes(node))
return true
Log.d(TAG, "Autofill web hint")
return parseNodeByHtmlAttributes(node)
}
else -> Log.d(TAG, "Autofill unsupported hint $it")
}
Expand All @@ -115,8 +111,6 @@ internal class StructureParser(private val structure: AssistStructure) {
}

private fun parseNodeByHtmlAttributes(node: AssistStructure.ViewNode): Boolean {
if (lockHint)
return false
val autofillId = node.autofillId
val nodHtml = node.htmlInfo
when (nodHtml?.tag?.toLowerCase(Locale.ENGLISH)) {
Expand All @@ -136,6 +130,7 @@ internal class StructureParser(private val structure: AssistStructure) {
"password" -> {
result?.passwordId = autofillId
Log.d(TAG, "Autofill password type: ${node.htmlInfo?.tag} ${node.htmlInfo?.attributes}")
return true
}
}
}
Expand Down
43 changes: 31 additions & 12 deletions app/src/main/java/com/kunzisoft/keepass/utils/BroadcastAction.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@
*/
package com.kunzisoft.keepass.utils

import android.app.AlarmManager
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Context.ALARM_SERVICE
import android.content.Intent
import android.content.IntentFilter
import android.os.Handler
import android.os.Build
import android.util.Log
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.Database
Expand All @@ -42,26 +45,34 @@ const val REMOVE_ENTRY_MAGIKEYBOARD_ACTION = "com.kunzisoft.keepass.REMOVE_ENTRY

class LockReceiver(var lockAction: () -> Unit) : BroadcastReceiver() {

private val screenOffHandler = Handler()
private var screenOffRunnable: Runnable? = null
var mLockPendingIntent: PendingIntent? = null

override fun onReceive(context: Context, intent: Intent) {

screenOffRunnable?.let { runnable ->
screenOffHandler.removeCallbacks(runnable)
}
// If allowed, lock and exit
if (!TimeoutHelper.temporarilyDisableTimeout) {
intent.action?.let {
when (it) {
Intent.ACTION_SCREEN_ON -> {
cancelLockPendingIntent(context)
}
Intent.ACTION_SCREEN_OFF -> {
if (PreferencesUtil.isLockDatabaseWhenScreenShutOffEnable(context)) {
screenOffRunnable = Runnable {
lockAction.invoke()
}
mLockPendingIntent = PendingIntent.getBroadcast(context,
4575,
Intent(intent).apply {
action = LOCK_ACTION
},
0)
// Launch the effective action after a small time
screenOffHandler.postDelayed(screenOffRunnable!!,
context.getString(R.string.timeout_screen_off).toLong())
val first: Long = System.currentTimeMillis() + context.getString(R.string.timeout_screen_off).toLong()
val alarmManager = context.getSystemService(ALARM_SERVICE) as AlarmManager?
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager?.setExact(AlarmManager.RTC_WAKEUP, first, mLockPendingIntent)
} else {
alarmManager?.set(AlarmManager.RTC_WAKEUP, first, mLockPendingIntent)
}
} else {
cancelLockPendingIntent(context)
}
}
LOCK_ACTION,
Expand All @@ -71,6 +82,14 @@ class LockReceiver(var lockAction: () -> Unit) : BroadcastReceiver() {
}
}
}

private fun cancelLockPendingIntent(context: Context) {
mLockPendingIntent?.let {
val alarmManager = context.getSystemService(ALARM_SERVICE) as AlarmManager?
alarmManager?.cancel(mLockPendingIntent)
mLockPendingIntent = null
}
}
}

fun Context.registerLockReceiver(lockReceiver: LockReceiver?,
Expand Down
65 changes: 58 additions & 7 deletions app/src/main/java/com/kunzisoft/keepass/utils/FileDatabaseInfo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,77 @@ package com.kunzisoft.keepass.utils

import android.content.Context
import android.net.Uri
import android.text.format.Formatter
import androidx.documentfile.provider.DocumentFile
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
import com.kunzisoft.keepass.settings.PreferencesUtil
import java.io.Serializable
import java.text.DateFormat
import java.util.*

class FileDatabaseInfo : FileInfo {
class FileDatabaseInfo : Serializable {

constructor(context: Context, fileUri: Uri): super(context, fileUri)
private var context: Context
private var documentFile: DocumentFile? = null
var fileUri: Uri?
private set

constructor(context: Context, filePath: String): super(context, filePath)
constructor(context: Context, fileUri: Uri) {
this.context = context
this.fileUri = fileUri
init()
}

constructor(context: Context, filePath: String) {
this.context = context
this.fileUri = UriUtil.parse(filePath)
init()
}

fun init() {
documentFile = UriUtil.getFileData(context, fileUri)
}

var exists: Boolean = false
get() {
return documentFile?.exists() ?: field
}
private set

var canRead: Boolean = false
get() {
return documentFile?.canRead() ?: field
}
private set

var canWrite: Boolean = false
get() {
return documentFile?.canWrite() ?: field
}
private set

fun getModificationString(): String? {
return documentFile?.lastModified()?.let {
DateFormat.getDateTimeInstance()
.format(Date(it))
}
}

fun getSizeString(): String? {
return documentFile?.let {
Formatter.formatFileSize(context, it.length())
}
}

fun retrieveDatabaseAlias(alias: String): String {
return when {
alias.isNotEmpty() -> alias
PreferencesUtil.isFullFilePathEnable(context) -> filePath ?: ""
else -> fileName ?: ""
PreferencesUtil.isFullFilePathEnable(context) -> fileUri?.path ?: ""
else -> if (exists) documentFile?.name ?: "" else fileUri?.path ?: ""
}
}

fun retrieveDatabaseTitle(titleCallback: (String)->Unit) {

fileUri?.let { fileUri ->
FileDatabaseHistoryAction.getInstance(context.applicationContext)
.getFileDatabaseHistory(fileUri) { fileDatabaseHistoryEntity ->
Expand All @@ -48,5 +100,4 @@ class FileDatabaseInfo : FileInfo {
}
}
}

}
Loading

0 comments on commit 32d235e

Please sign in to comment.