mirror of
https://github.com/Kunzisoft/KeePassDX.git
synced 2025-12-04 15:49:33 +01:00
Merge branch 'feature/Button_Block_Autofill' into develop
This commit is contained in:
@@ -69,7 +69,7 @@ android {
|
||||
buildConfigField "String", "BUILD_VERSION", "\"free\""
|
||||
buildConfigField "boolean", "FULL_VERSION", "false"
|
||||
buildConfigField "boolean", "CLOSED_STORE", "true"
|
||||
buildConfigField "String[]", "STYLES_DISABLED", "{\"KeepassDXStyle_Dark\",\"KeepassDXStyle_Blue\",\"KeepassDXStyle_Red\",\"KeepassDXStyle_Purple\"}"
|
||||
buildConfigField "String[]", "STYLES_DISABLED", "{}"
|
||||
buildConfigField "String[]", "ICON_PACKS_DISABLED", "{}"
|
||||
manifestPlaceholders = [ googleAndroidBackupAPIKey:"AEdPqrEAAAAIbRfbV8fHLItXo8OcHwrO0sSNblqhPwkc0DPTqg" ]
|
||||
}
|
||||
|
||||
@@ -26,25 +26,43 @@ import android.content.Intent
|
||||
import android.content.IntentSender
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.widget.Toast
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.autofill.AutofillHelper
|
||||
import com.kunzisoft.keepass.autofill.KeeAutofillService
|
||||
import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.database.search.SearchHelper
|
||||
import com.kunzisoft.keepass.model.SearchInfo
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
class AutofillLauncherActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
||||
// Build search param
|
||||
val searchInfo = SearchInfo().apply {
|
||||
applicationId = intent.getStringExtra(KEY_SEARCH_APPLICATION_ID)
|
||||
webDomain = intent.getStringExtra(KEY_SEARCH_DOMAIN)
|
||||
}
|
||||
|
||||
// Pass extra for Autofill (EXTRA_ASSIST_STRUCTURE)
|
||||
val assistStructure = AutofillHelper.retrieveAssistStructure(intent)
|
||||
if (assistStructure != null) {
|
||||
// Build search param
|
||||
val searchInfo = SearchInfo().apply {
|
||||
applicationId = intent.getStringExtra(KEY_SEARCH_APPLICATION_ID)
|
||||
webDomain = intent.getStringExtra(KEY_SEARCH_DOMAIN)
|
||||
}
|
||||
|
||||
if (assistStructure == null) {
|
||||
setResult(Activity.RESULT_CANCELED)
|
||||
finish()
|
||||
} else if (!KeeAutofillService.searchAllowedFor(searchInfo.applicationId,
|
||||
PreferencesUtil.applicationIdBlocklist(this))
|
||||
|| !KeeAutofillService.searchAllowedFor(searchInfo.webDomain,
|
||||
PreferencesUtil.webDomainBlocklist(this))) {
|
||||
// If item not allowed, show a toast
|
||||
Toast.makeText(this.applicationContext, R.string.autofill_block_restart, Toast.LENGTH_LONG).show()
|
||||
setResult(Activity.RESULT_CANCELED)
|
||||
finish()
|
||||
} else {
|
||||
// If database is open
|
||||
SearchHelper.checkAutoSearchInfo(this,
|
||||
Database.getInstance(),
|
||||
@@ -57,17 +75,17 @@ class AutofillLauncherActivity : AppCompatActivity() {
|
||||
{
|
||||
// Show the database UI to select the entry
|
||||
GroupActivity.launchForAutofillResult(this,
|
||||
assistStructure)
|
||||
assistStructure,
|
||||
false,
|
||||
searchInfo)
|
||||
},
|
||||
{
|
||||
// If database not open
|
||||
FileDatabaseSelectActivity.launchForAutofillResult(this,
|
||||
assistStructure, searchInfo)
|
||||
assistStructure,
|
||||
searchInfo)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
setResult(Activity.RESULT_CANCELED)
|
||||
finish()
|
||||
}
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
|
||||
import com.kunzisoft.keepass.database.element.Database
|
||||
import com.kunzisoft.keepass.database.search.SearchHelper
|
||||
@@ -54,14 +55,14 @@ class EntrySelectionLauncherActivity : AppCompatActivity() {
|
||||
else -> {}
|
||||
}
|
||||
|
||||
// Setting to integrate Magikeyboard
|
||||
val searchShareForMagikeyboard = PreferencesUtil.isKeyboardSearchShareEnable(this)
|
||||
|
||||
// Build search param
|
||||
val searchInfo = SearchInfo().apply {
|
||||
webDomain = sharedWebDomain
|
||||
}
|
||||
|
||||
// Setting to integrate Magikeyboard
|
||||
val searchShareForMagikeyboard = PreferencesUtil.isKeyboardSearchShareEnable(this)
|
||||
|
||||
// If database is open
|
||||
SearchHelper.checkAutoSearchInfo(this,
|
||||
Database.getInstance(),
|
||||
@@ -72,29 +73,41 @@ class EntrySelectionLauncherActivity : AppCompatActivity() {
|
||||
if (items.size == 1) {
|
||||
// Automatically populate keyboard
|
||||
val entryPopulate = items[0]
|
||||
populateKeyboardAndMoveAppToBackground(this, entryPopulate, intent)
|
||||
populateKeyboardAndMoveAppToBackground(this,
|
||||
entryPopulate,
|
||||
intent)
|
||||
} else {
|
||||
// Select the one we want
|
||||
GroupActivity.launchForEntrySelectionResult(this, searchInfo)
|
||||
GroupActivity.launchForEntrySelectionResult(this,
|
||||
true,
|
||||
searchInfo)
|
||||
}
|
||||
} else {
|
||||
GroupActivity.launch(this, searchInfo)
|
||||
GroupActivity.launch(this,
|
||||
true,
|
||||
searchInfo)
|
||||
}
|
||||
},
|
||||
{
|
||||
// Show the database UI to select the entry
|
||||
if (searchShareForMagikeyboard) {
|
||||
GroupActivity.launchForEntrySelectionResult(this)
|
||||
GroupActivity.launchForEntrySelectionResult(this,
|
||||
false,
|
||||
searchInfo)
|
||||
} else {
|
||||
GroupActivity.launch(this)
|
||||
GroupActivity.launch(this,
|
||||
false,
|
||||
searchInfo)
|
||||
}
|
||||
},
|
||||
{
|
||||
// If database not open
|
||||
if (searchShareForMagikeyboard) {
|
||||
FileDatabaseSelectActivity.launchForEntrySelectionResult(this, searchInfo)
|
||||
FileDatabaseSelectActivity.launchForEntrySelectionResult(this,
|
||||
searchInfo)
|
||||
} else {
|
||||
FileDatabaseSelectActivity.launch(this, searchInfo)
|
||||
FileDatabaseSelectActivity.launch(this,
|
||||
searchInfo)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -55,7 +55,6 @@ import com.kunzisoft.keepass.model.SearchInfo
|
||||
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_CREATE_TASK
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import com.kunzisoft.keepass.utils.*
|
||||
import com.kunzisoft.keepass.view.SpecialModeView
|
||||
import com.kunzisoft.keepass.view.asError
|
||||
import kotlinx.android.synthetic.main.activity_file_selection.*
|
||||
import java.io.FileNotFoundException
|
||||
@@ -69,7 +68,6 @@ class FileDatabaseSelectActivity : SpecialModeActivity(),
|
||||
private var databaseButtonsContainerView: View? = null
|
||||
private var createDatabaseButtonView: View? = null
|
||||
private var openDatabaseButtonView: View? = null
|
||||
private var specialModeView: SpecialModeView? = null
|
||||
|
||||
// Adapter to manage database history list
|
||||
private var mAdapterDatabaseHistory: FileDatabaseHistoryAdapter? = null
|
||||
@@ -115,9 +113,6 @@ class FileDatabaseSelectActivity : SpecialModeActivity(),
|
||||
}
|
||||
}
|
||||
|
||||
// Special mode view
|
||||
specialModeView = findViewById(R.id.special_mode_view)
|
||||
|
||||
// History list
|
||||
val fileDatabaseHistoryRecyclerView = findViewById<RecyclerView>(R.id.file_list)
|
||||
fileDatabaseHistoryRecyclerView.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false)
|
||||
@@ -241,11 +236,13 @@ class FileDatabaseSelectActivity : SpecialModeActivity(),
|
||||
EntrySelectionHelper.doEntrySelectionAction(intent,
|
||||
{
|
||||
GroupActivity.launch(this@FileDatabaseSelectActivity,
|
||||
false,
|
||||
searchInfo,
|
||||
readOnly)
|
||||
},
|
||||
{
|
||||
GroupActivity.launchForEntrySelectionResult(this@FileDatabaseSelectActivity,
|
||||
false,
|
||||
searchInfo,
|
||||
readOnly)
|
||||
// Do not keep history
|
||||
@@ -255,6 +252,7 @@ class FileDatabaseSelectActivity : SpecialModeActivity(),
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
GroupActivity.launchForAutofillResult(this@FileDatabaseSelectActivity,
|
||||
assistStructure,
|
||||
false,
|
||||
searchInfo,
|
||||
readOnly)
|
||||
}
|
||||
@@ -271,14 +269,6 @@ class FileDatabaseSelectActivity : SpecialModeActivity(),
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
// To show the selection mode
|
||||
specialModeView?.apply {
|
||||
visible = mSelectionMode
|
||||
onCancelButtonClickListener = View.OnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
// Show open and create button or special mode
|
||||
if (mSelectionMode) {
|
||||
// Disable buttons if in selection mode or request for autofill
|
||||
|
||||
@@ -94,7 +94,6 @@ class GroupActivity : LockingActivity(),
|
||||
private var toolbarAction: ToolbarAction? = null
|
||||
private var iconView: ImageView? = null
|
||||
private var numberChildrenView: TextView? = null
|
||||
private var specialModeView: SpecialModeView? = null
|
||||
private var addNodeButtonView: AddNodeButtonView? = null
|
||||
private var groupNameView: TextView? = null
|
||||
|
||||
@@ -136,7 +135,6 @@ class GroupActivity : LockingActivity(),
|
||||
searchTitleView = findViewById(R.id.search_title)
|
||||
groupNameView = findViewById(R.id.group_name)
|
||||
toolbarAction = findViewById(R.id.toolbar_action)
|
||||
specialModeView = findViewById(R.id.special_mode_view)
|
||||
lockView = findViewById(R.id.lock_button)
|
||||
|
||||
lockView?.setOnClickListener {
|
||||
@@ -286,7 +284,7 @@ class GroupActivity : LockingActivity(),
|
||||
|
||||
intent?.let { intentNotNull ->
|
||||
// To transform KEY_SEARCH_INFO in ACTION_SEARCH
|
||||
manageSearchInfoIntent(intent)
|
||||
manageSearchInfoIntent(intentNotNull)
|
||||
Log.d(TAG, "setNewIntent: $intentNotNull")
|
||||
setIntent(intentNotNull)
|
||||
mCurrentGroupIsASearch = if (Intent.ACTION_SEARCH == intentNotNull.action) {
|
||||
@@ -306,9 +304,9 @@ class GroupActivity : LockingActivity(),
|
||||
private fun manageSearchInfoIntent(intent: Intent): Boolean {
|
||||
// To relaunch the activity as ACTION_SEARCH
|
||||
val searchInfo: SearchInfo? = intent.getParcelableExtra(KEY_SEARCH_INFO)
|
||||
if (searchInfo != null) {
|
||||
val autoSearch = intent.getBooleanExtra(AUTO_SEARCH_KEY, false)
|
||||
if (searchInfo != null && autoSearch) {
|
||||
intent.action = Intent.ACTION_SEARCH
|
||||
intent.removeExtra(KEY_SEARCH_INFO)
|
||||
intent.putExtra(SearchManager.QUERY, searchInfo.getSearchString(this))
|
||||
return true
|
||||
}
|
||||
@@ -463,24 +461,6 @@ class GroupActivity : LockingActivity(),
|
||||
// Assign number of children
|
||||
refreshNumberOfChildren()
|
||||
|
||||
// Show selection mode message if needed
|
||||
specialModeView?.apply {
|
||||
visible = mSelectionMode
|
||||
onCancelButtonClickListener = View.OnClickListener {
|
||||
// To remove the navigation history and
|
||||
EntrySelectionHelper.removeEntrySelectionModeFromIntent(intent)
|
||||
val fragmentManager = supportFragmentManager
|
||||
if (mSelectionModeCountBackStack > 0) {
|
||||
for (selectionMode in 0 .. mSelectionModeCountBackStack) {
|
||||
fragmentManager.popBackStack()
|
||||
}
|
||||
}
|
||||
// Reinit the counter for navigation history
|
||||
mSelectionModeCountBackStack = 0
|
||||
backToTheAppCaller()
|
||||
}
|
||||
}
|
||||
|
||||
// Show button if allowed
|
||||
addNodeButtonView?.apply {
|
||||
|
||||
@@ -498,6 +478,20 @@ class GroupActivity : LockingActivity(),
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCancelSpecialMode() {
|
||||
// To remove the navigation history and
|
||||
EntrySelectionHelper.removeEntrySelectionModeFromIntent(intent)
|
||||
val fragmentManager = supportFragmentManager
|
||||
if (mSelectionModeCountBackStack > 0) {
|
||||
for (selectionMode in 0 .. mSelectionModeCountBackStack) {
|
||||
fragmentManager.popBackStack()
|
||||
}
|
||||
}
|
||||
// Reinit the counter for navigation history
|
||||
mSelectionModeCountBackStack = 0
|
||||
backToTheAppCaller()
|
||||
}
|
||||
|
||||
private fun refreshNumberOfChildren() {
|
||||
numberChildrenView?.apply {
|
||||
if (PreferencesUtil.showNumberEntries(context)) {
|
||||
@@ -1002,6 +996,8 @@ class GroupActivity : LockingActivity(),
|
||||
}
|
||||
// Else in root, lock if needed
|
||||
else {
|
||||
intent.removeExtra(AUTO_SEARCH_KEY)
|
||||
intent.removeExtra(KEY_SEARCH_INFO)
|
||||
if (PreferencesUtil.isLockDatabaseWhenBackButtonOnRootClicked(this)) {
|
||||
lockAndExit()
|
||||
super.onBackPressed()
|
||||
@@ -1023,6 +1019,7 @@ class GroupActivity : LockingActivity(),
|
||||
private const val LIST_NODES_FRAGMENT_TAG = "LIST_NODES_FRAGMENT_TAG"
|
||||
private const val SEARCH_FRAGMENT_TAG = "SEARCH_FRAGMENT_TAG"
|
||||
private const val OLD_GROUP_TO_UPDATE_KEY = "OLD_GROUP_TO_UPDATE_KEY"
|
||||
private const val AUTO_SEARCH_KEY = "AUTO_SEARCH_KEY"
|
||||
|
||||
private fun buildIntent(context: Context,
|
||||
group: Group?,
|
||||
@@ -1060,12 +1057,14 @@ class GroupActivity : LockingActivity(),
|
||||
* -------------------------
|
||||
*/
|
||||
fun launch(context: Context,
|
||||
autoSearch: Boolean = false,
|
||||
searchInfo: SearchInfo? = null,
|
||||
readOnly: Boolean = PreferencesUtil.enableReadOnlyDatabase(context)) {
|
||||
checkTimeAndBuildIntent(context, null, readOnly) { intent ->
|
||||
searchInfo?.let {
|
||||
intent.putExtra(KEY_SEARCH_INFO, it)
|
||||
}
|
||||
intent.putExtra(AUTO_SEARCH_KEY, autoSearch)
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
||||
@@ -1076,9 +1075,11 @@ class GroupActivity : LockingActivity(),
|
||||
* -------------------------
|
||||
*/
|
||||
fun launchForEntrySelectionResult(context: Context,
|
||||
autoSearch: Boolean = false,
|
||||
searchInfo: SearchInfo? = null,
|
||||
readOnly: Boolean = PreferencesUtil.enableReadOnlyDatabase(context)) {
|
||||
checkTimeAndBuildIntent(context, null, readOnly) { intent ->
|
||||
intent.putExtra(AUTO_SEARCH_KEY, autoSearch)
|
||||
EntrySelectionHelper.startActivityForEntrySelectionResult(context, intent, searchInfo)
|
||||
}
|
||||
}
|
||||
@@ -1091,9 +1092,11 @@ class GroupActivity : LockingActivity(),
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
fun launchForAutofillResult(activity: Activity,
|
||||
assistStructure: AssistStructure,
|
||||
autoSearch: Boolean = false,
|
||||
searchInfo: SearchInfo? = null,
|
||||
readOnly: Boolean = PreferencesUtil.enableReadOnlyDatabase(activity)) {
|
||||
checkTimeAndBuildIntent(activity, null, readOnly) { intent ->
|
||||
intent.putExtra(AUTO_SEARCH_KEY, autoSearch)
|
||||
AutofillHelper.startActivityForAutofillResult(activity, intent, assistStructure, searchInfo)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,6 @@ import com.kunzisoft.keepass.utils.MenuUtil
|
||||
import com.kunzisoft.keepass.utils.UriUtil
|
||||
import com.kunzisoft.keepass.view.AdvancedUnlockInfoView
|
||||
import com.kunzisoft.keepass.view.KeyFileSelectionView
|
||||
import com.kunzisoft.keepass.view.SpecialModeView
|
||||
import com.kunzisoft.keepass.view.asError
|
||||
import kotlinx.android.synthetic.main.activity_password.*
|
||||
import java.io.FileNotFoundException
|
||||
@@ -78,7 +77,6 @@ open class PasswordActivity : SpecialModeActivity() {
|
||||
|
||||
// Views
|
||||
private var toolbar: Toolbar? = null
|
||||
private var specialModeView: SpecialModeView? = null
|
||||
private var filenameView: TextView? = null
|
||||
private var passwordView: EditText? = null
|
||||
private var keyFileSelectionView: KeyFileSelectionView? = null
|
||||
@@ -125,7 +123,6 @@ open class PasswordActivity : SpecialModeActivity() {
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
supportActionBar?.setDisplayShowHomeEnabled(true)
|
||||
|
||||
specialModeView = findViewById(R.id.special_mode_view)
|
||||
confirmButtonView = findViewById(R.id.activity_password_open_button)
|
||||
filenameView = findViewById(R.id.filename)
|
||||
passwordView = findViewById(R.id.password)
|
||||
@@ -266,9 +263,10 @@ open class PasswordActivity : SpecialModeActivity() {
|
||||
EntrySelectionHelper.doEntrySelectionAction(intent,
|
||||
{
|
||||
GroupActivity.launch(this@PasswordActivity,
|
||||
true,
|
||||
searchInfo,
|
||||
readOnly)
|
||||
// Remove the search info from intent
|
||||
// Finish activity if no search info
|
||||
if (searchInfo != null) {
|
||||
finish()
|
||||
}
|
||||
@@ -285,13 +283,16 @@ open class PasswordActivity : SpecialModeActivity() {
|
||||
intent)
|
||||
} else {
|
||||
// Select the one we want
|
||||
GroupActivity.launchForEntrySelectionResult(this, searchInfo)
|
||||
GroupActivity.launchForEntrySelectionResult(this,
|
||||
true,
|
||||
searchInfo)
|
||||
}
|
||||
},
|
||||
{
|
||||
// Here no search info found
|
||||
// Here no search info found, disable auto search
|
||||
GroupActivity.launchForEntrySelectionResult(this@PasswordActivity,
|
||||
null,
|
||||
false,
|
||||
searchInfo,
|
||||
readOnly)
|
||||
},
|
||||
{
|
||||
@@ -312,10 +313,11 @@ open class PasswordActivity : SpecialModeActivity() {
|
||||
finish()
|
||||
},
|
||||
{
|
||||
// Here no search info found
|
||||
// Here no search info found, disable auto search
|
||||
GroupActivity.launchForAutofillResult(this@PasswordActivity,
|
||||
assistStructure,
|
||||
null,
|
||||
false,
|
||||
searchInfo,
|
||||
readOnly)
|
||||
},
|
||||
{
|
||||
@@ -340,14 +342,6 @@ open class PasswordActivity : SpecialModeActivity() {
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
// To show the selection mode
|
||||
specialModeView?.apply {
|
||||
visible = mSelectionMode
|
||||
onCancelButtonClickListener = View.OnClickListener {
|
||||
onBackPressed()
|
||||
}
|
||||
}
|
||||
|
||||
if (Database.getInstance().loaded) {
|
||||
launchGroupActivity()
|
||||
} else {
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
package com.kunzisoft.keepass.activities.selection
|
||||
|
||||
import android.os.Build
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper
|
||||
import com.kunzisoft.keepass.activities.stylish.StylishActivity
|
||||
import com.kunzisoft.keepass.autofill.AutofillHelper
|
||||
import com.kunzisoft.keepass.model.SearchInfo
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
import com.kunzisoft.keepass.view.SpecialModeView
|
||||
|
||||
/**
|
||||
* Activity to manage special mode (ie: selection mode)
|
||||
@@ -14,6 +20,12 @@ abstract class SpecialModeActivity : StylishActivity() {
|
||||
|
||||
protected var mAutofillSelection: Boolean = false
|
||||
|
||||
private var specialModeView: SpecialModeView? = null
|
||||
|
||||
open fun onCancelSpecialMode() {
|
||||
onBackPressed()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
|
||||
@@ -21,5 +33,58 @@ abstract class SpecialModeActivity : StylishActivity() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
mAutofillSelection = AutofillHelper.retrieveAssistStructure(intent) != null
|
||||
}
|
||||
|
||||
val searchInfo: SearchInfo? = intent.getParcelableExtra(EntrySelectionHelper.KEY_SEARCH_INFO)
|
||||
|
||||
// To show the selection mode
|
||||
specialModeView = findViewById(R.id.special_mode_view)
|
||||
specialModeView?.apply {
|
||||
// Populate title
|
||||
val typeModeId = if (mAutofillSelection)
|
||||
R.string.autofill
|
||||
else
|
||||
R.string.magic_keyboard_title
|
||||
title = "${resources.getString(R.string.selection_mode)} (${getString(typeModeId)})"
|
||||
// Populate subtitle
|
||||
subtitle = searchInfo?.getName(resources)
|
||||
|
||||
// Show the toolbar or not
|
||||
visible = mSelectionMode
|
||||
|
||||
// Add back listener
|
||||
onCancelButtonClickListener = View.OnClickListener {
|
||||
onCancelSpecialMode()
|
||||
}
|
||||
|
||||
// Create menu
|
||||
menu.clear()
|
||||
if (mAutofillSelection) {
|
||||
menuInflater.inflate(R.menu.autofill, menu)
|
||||
setOnMenuItemClickListener { menuItem ->
|
||||
when (menuItem.itemId) {
|
||||
R.id.menu_block_autofill -> {
|
||||
blockAutofill(searchInfo)
|
||||
}
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun blockAutofill(searchInfo: SearchInfo?) {
|
||||
val webDomain = searchInfo?.webDomain
|
||||
val applicationId = searchInfo?.applicationId
|
||||
if (webDomain != null) {
|
||||
PreferencesUtil.addWebDomainToBlocklist(this,
|
||||
webDomain)
|
||||
} else if (applicationId != null) {
|
||||
PreferencesUtil.addApplicationIdToBlocklist(this,
|
||||
applicationId)
|
||||
}
|
||||
onCancelSpecialMode()
|
||||
Toast.makeText(this.applicationContext,
|
||||
R.string.autofill_block_restart,
|
||||
Toast.LENGTH_LONG).show()
|
||||
}
|
||||
}
|
||||
@@ -119,29 +119,33 @@ object AutofillHelper {
|
||||
* Build the Autofill response for many entry
|
||||
*/
|
||||
fun buildResponse(activity: Activity, entriesInfo: List<EntryInfo>) {
|
||||
var setResultOk = false
|
||||
activity.intent?.extras?.let { extras ->
|
||||
if (extras.containsKey(ASSIST_STRUCTURE)) {
|
||||
activity.intent?.getParcelableExtra<AssistStructure>(ASSIST_STRUCTURE)?.let { structure ->
|
||||
StructureParser(structure).parse()?.let { result ->
|
||||
// New Response
|
||||
val responseBuilder = FillResponse.Builder()
|
||||
entriesInfo.forEach {
|
||||
responseBuilder.addDataset(buildDataset(activity, it, result))
|
||||
if (entriesInfo.isEmpty()) {
|
||||
activity.setResult(Activity.RESULT_CANCELED)
|
||||
} else {
|
||||
var setResultOk = false
|
||||
activity.intent?.extras?.let { extras ->
|
||||
if (extras.containsKey(ASSIST_STRUCTURE)) {
|
||||
activity.intent?.getParcelableExtra<AssistStructure>(ASSIST_STRUCTURE)?.let { structure ->
|
||||
StructureParser(structure).parse()?.let { result ->
|
||||
// New Response
|
||||
val responseBuilder = FillResponse.Builder()
|
||||
entriesInfo.forEach {
|
||||
responseBuilder.addDataset(buildDataset(activity, it, result))
|
||||
}
|
||||
val mReplyIntent = Intent()
|
||||
Log.d(activity.javaClass.name, "Successed Autofill auth.")
|
||||
mReplyIntent.putExtra(
|
||||
AutofillManager.EXTRA_AUTHENTICATION_RESULT,
|
||||
responseBuilder.build())
|
||||
setResultOk = true
|
||||
activity.setResult(Activity.RESULT_OK, mReplyIntent)
|
||||
}
|
||||
val mReplyIntent = Intent()
|
||||
Log.d(activity.javaClass.name, "Successed Autofill auth.")
|
||||
mReplyIntent.putExtra(
|
||||
AutofillManager.EXTRA_AUTHENTICATION_RESULT,
|
||||
responseBuilder.build())
|
||||
setResultOk = true
|
||||
activity.setResult(Activity.RESULT_OK, mReplyIntent)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!setResultOk) {
|
||||
Log.w(activity.javaClass.name, "Failed Autofill auth.")
|
||||
activity.setResult(Activity.RESULT_CANCELED)
|
||||
if (!setResultOk) {
|
||||
Log.w(activity.javaClass.name, "Failed Autofill auth.")
|
||||
activity.setResult(Activity.RESULT_CANCELED)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,27 +57,8 @@ class KeeAutofillService : AutofillService() {
|
||||
StructureParser(latestStructure).parse()?.let { parseResult ->
|
||||
|
||||
// Build search info only if applicationId or webDomain are not blocked
|
||||
var searchAllowed = true
|
||||
parseResult.applicationId?.let { appId ->
|
||||
if (applicationIdBlocklist?.any { appIdBlocked ->
|
||||
appId.contains(appIdBlocked)
|
||||
} == true
|
||||
) {
|
||||
searchAllowed = false
|
||||
Log.d(TAG, "Autofill not allowed for $appId")
|
||||
}
|
||||
}
|
||||
parseResult.domain?.let { domain ->
|
||||
if (webDomainBlocklist?.any { webDomainBlocked ->
|
||||
domain.contains(webDomainBlocked)
|
||||
} == true
|
||||
) {
|
||||
searchAllowed = false
|
||||
Log.d(TAG, "Autofill not allowed for $domain")
|
||||
}
|
||||
}
|
||||
|
||||
if (searchAllowed) {
|
||||
if (searchAllowedFor(parseResult.applicationId, applicationIdBlocklist)
|
||||
&& searchAllowedFor(parseResult.domain, webDomainBlocklist)) {
|
||||
val searchInfo = SearchInfo().apply {
|
||||
applicationId = parseResult.applicationId
|
||||
webDomain = parseResult.domain
|
||||
@@ -150,5 +131,18 @@ class KeeAutofillService : AutofillService() {
|
||||
|
||||
companion object {
|
||||
private val TAG = KeeAutofillService::class.java.name
|
||||
|
||||
fun searchAllowedFor(element: String?, blockList: Set<String>?): Boolean {
|
||||
element?.let { elementNotNull ->
|
||||
if (blockList?.any { appIdBlocked ->
|
||||
elementNotNull.contains(appIdBlocked)
|
||||
} == true
|
||||
) {
|
||||
Log.d(TAG, "Autofill not allowed for $elementNotNull")
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ class SearchInfo : ObjectNameResource, Parcelable {
|
||||
}
|
||||
|
||||
override fun getName(resources: Resources): String {
|
||||
return applicationId ?: webDomain ?: ""
|
||||
return toString()
|
||||
}
|
||||
|
||||
fun containsOnlyNullValues(): Boolean {
|
||||
|
||||
@@ -20,8 +20,10 @@
|
||||
package com.kunzisoft.keepass.settings
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Resources
|
||||
import android.net.Uri
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.kunzisoft.keepass.BuildConfig
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.database.element.SortNodeEnum
|
||||
import com.kunzisoft.keepass.timeout.TimeoutHelper
|
||||
@@ -373,10 +375,20 @@ object PreferencesUtil {
|
||||
context.resources.getBoolean(R.bool.autofill_auto_search_default))
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the default Blocklist for application ID, including the current app
|
||||
*/
|
||||
fun getDefaultApplicationIdBlocklist(resources: Resources?): Set<String> {
|
||||
return resources?.getStringArray(R.array.autofill_application_id_blocklist_default)
|
||||
?.toMutableSet()?.apply {
|
||||
add(BuildConfig.APPLICATION_ID)
|
||||
} ?: emptySet()
|
||||
}
|
||||
|
||||
fun applicationIdBlocklist(context: Context): Set<String> {
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
return prefs.getStringSet(context.getString(R.string.autofill_application_id_blocklist_key),
|
||||
context.resources.getStringArray(R.array.autofill_application_id_blocklist_default).toMutableSet())
|
||||
getDefaultApplicationIdBlocklist(context.resources))
|
||||
?: emptySet()
|
||||
}
|
||||
|
||||
@@ -386,4 +398,22 @@ object PreferencesUtil {
|
||||
context.resources.getStringArray(R.array.autofill_web_domain_blocklist_default).toMutableSet())
|
||||
?: emptySet()
|
||||
}
|
||||
|
||||
fun addApplicationIdToBlocklist(context: Context, applicationId: String) {
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
val setItems: MutableSet<String> = applicationIdBlocklist(context).toMutableSet()
|
||||
setItems.add(applicationId)
|
||||
prefs.edit()
|
||||
.putStringSet(context.getString(R.string.autofill_application_id_blocklist_key), setItems)
|
||||
.apply()
|
||||
}
|
||||
|
||||
fun addWebDomainToBlocklist(context: Context, webDomain: String) {
|
||||
val prefs = PreferenceManager.getDefaultSharedPreferences(context)
|
||||
val setItems: MutableSet<String> = webDomainBlocklist(context).toMutableSet()
|
||||
setItems.add(webDomain)
|
||||
prefs.edit()
|
||||
.putStringSet(context.getString(R.string.autofill_web_domain_blocklist_key), setItems)
|
||||
.apply()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
package com.kunzisoft.keepass.settings.preferencedialogfragment
|
||||
|
||||
import android.os.Bundle
|
||||
import com.kunzisoft.keepass.R
|
||||
import com.kunzisoft.keepass.model.SearchInfo
|
||||
import com.kunzisoft.keepass.settings.PreferencesUtil
|
||||
|
||||
class AutofillBlocklistAppIdPreferenceDialogFragmentCompat
|
||||
: AutofillBlocklistPreferenceDialogFragmentCompat() {
|
||||
@@ -34,10 +34,7 @@ class AutofillBlocklistAppIdPreferenceDialogFragmentCompat
|
||||
}
|
||||
|
||||
override fun getDefaultValues(): Set<String> {
|
||||
return context?.resources
|
||||
?.getStringArray(R.array.autofill_application_id_blocklist_default)
|
||||
?.toMutableSet()
|
||||
?: emptySet()
|
||||
return PreferencesUtil.getDefaultApplicationIdBlocklist(this.resources)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2019 Jeremy Jamet / Kunzisoft.
|
||||
* Copyright 2020 Jeremy Jamet / Kunzisoft.
|
||||
*
|
||||
* This file is part of KeePassDX.
|
||||
*
|
||||
@@ -21,39 +21,24 @@ package com.kunzisoft.keepass.view
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import com.kunzisoft.keepass.R
|
||||
|
||||
class SpecialModeView @JvmOverloads constructor(context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyle: Int = 0)
|
||||
: ConstraintLayout(context, attrs, defStyle) {
|
||||
|
||||
private var cancelButton: View? = null
|
||||
private var titleView: TextView? = null
|
||||
defStyle: Int = androidx.appcompat.R.attr.toolbarStyle)
|
||||
: Toolbar(context, attrs, defStyle) {
|
||||
|
||||
init {
|
||||
val inflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater?
|
||||
inflater?.inflate(R.layout.selection_mode_view, this)
|
||||
|
||||
cancelButton = findViewById(R.id.special_mode_cancel_button)
|
||||
titleView = findViewById(R.id.special_mode_title_view)
|
||||
setNavigationIcon(R.drawable.ic_close_white_24dp)
|
||||
title = resources.getString(R.string.selection_mode)
|
||||
}
|
||||
|
||||
var title: CharSequence?
|
||||
get() {
|
||||
return titleView?.text
|
||||
}
|
||||
set(value) {
|
||||
titleView?.text = value
|
||||
}
|
||||
|
||||
var onCancelButtonClickListener: OnClickListener? = null
|
||||
set(value) {
|
||||
cancelButton?.setOnClickListener(value)
|
||||
if (value != null)
|
||||
setNavigationOnClickListener(value)
|
||||
}
|
||||
|
||||
var visible: Boolean = false
|
||||
|
||||
9
app/src/main/res/drawable/ic_block_white_24dp.xml
Normal file
9
app/src/main/res/drawable/ic_block_white_24dp.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM4,12c0,-4.42 3.58,-8 8,-8 1.85,0 3.55,0.63 4.9,1.69L5.69,16.9C4.63,15.55 4,13.85 4,12zM12,20c-1.85,0 -3.55,-0.63 -4.9,-1.69L18.31,7.1C19.37,8.45 20,10.15 20,12c0,4.42 -3.58,8 -8,8z"/>
|
||||
</vector>
|
||||
@@ -30,6 +30,9 @@
|
||||
android:id="@+id/special_mode_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="?attr/specialToolbarAppearance"
|
||||
app:titleTextAppearance="@style/KeepassDXStyle.TextAppearance.Toolbar.Special.Title"
|
||||
app:subtitleTextAppearance="@style/KeepassDXStyle.TextAppearance.Toolbar.Special.SubTitle"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
android:id="@+id/special_mode_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="?attr/specialToolbarAppearance"
|
||||
app:titleTextAppearance="@style/KeepassDXStyle.TextAppearance.Toolbar.Special.Title"
|
||||
app:subtitleTextAppearance="@style/KeepassDXStyle.TextAppearance.Toolbar.Special.SubTitle"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
@@ -159,7 +162,7 @@
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:elevation="4dp"
|
||||
android:theme="?attr/toolbarBottomAppearance"
|
||||
android:theme="?attr/actionToolbarAppearance"
|
||||
android:background="?attr/colorAccent"
|
||||
tools:targetApi="lollipop" />
|
||||
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
android:id="@+id/special_mode_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="?attr/specialToolbarAppearance"
|
||||
app:titleTextAppearance="@style/KeepassDXStyle.TextAppearance.Toolbar.Special.Title"
|
||||
app:subtitleTextAppearance="@style/KeepassDXStyle.TextAppearance.Toolbar.Special.SubTitle"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
@@ -218,7 +221,7 @@
|
||||
android:paddingLeft="24dp"
|
||||
android:paddingEnd="24dp"
|
||||
android:paddingRight="24dp"
|
||||
style="@style/KeepassDXStyle.TextAppearance.TinyText"
|
||||
style="@style/KeepassDXStyle.TextAppearance.Tiny"
|
||||
android:text="@string/warning_database_link_revoked"
|
||||
android:textColor="?attr/textColorInverse"
|
||||
android:background="?attr/colorAccent"
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
android:id="@+id/item_attachment_compression"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
style="@style/KeepassDXStyle.TextAppearance.TinyText"
|
||||
style="@style/KeepassDXStyle.TextAppearance.Tiny"
|
||||
android:firstBaselineToTopHeight="0dp"
|
||||
android:includeFontPadding="false"
|
||||
android:paddingStart="8dp"
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/special_mode_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="4dp"
|
||||
android:paddingBottom="4dp"
|
||||
android:paddingStart="8dp"
|
||||
android:paddingLeft="8dp"
|
||||
android:paddingEnd="8dp"
|
||||
android:paddingRight="8dp"
|
||||
android:background="?attr/colorPrimaryDark">
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/special_mode_cancel_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/ic_close_white_24dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginRight="8dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:text="@string/entry_cancel"/>
|
||||
<androidx.appcompat.widget.AppCompatTextView
|
||||
android:id="@+id/special_mode_title_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/selection_mode"
|
||||
android:textColor="?attr/textColorInverse"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
27
app/src/main/res/menu/autofill.xml
Normal file
27
app/src/main/res/menu/autofill.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
Copyright 2020 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/>.
|
||||
-->
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item android:id="@+id/menu_block_autofill"
|
||||
android:icon="@drawable/ic_block_white_24dp"
|
||||
android:title="@string/autofill_block"
|
||||
android:orderInCategory="1"
|
||||
app:showAsAction="ifRoom" />
|
||||
</menu>
|
||||
@@ -19,7 +19,8 @@
|
||||
-->
|
||||
<resources>
|
||||
<attr name="toolbarAppearance" format="reference" />
|
||||
<attr name="toolbarBottomAppearance" format="reference" />
|
||||
<attr name="specialToolbarAppearance" format="reference" />
|
||||
<attr name="actionToolbarAppearance" format="reference" />
|
||||
<attr name="toolbarPopupAppearance" format="reference" />
|
||||
|
||||
<attr name="colorAccentLight" format="reference|color" />
|
||||
|
||||
@@ -42,6 +42,9 @@
|
||||
<color name="blue_dark">#1976D2</color>
|
||||
<color name="blue_darker">#1565C0</color>
|
||||
|
||||
<color name="cyan_lighter">#33b5e5</color>
|
||||
<color name="cyan">#2c7a96</color>
|
||||
|
||||
<color name="red_lighter">#ef9a9a</color>
|
||||
<color name="red_light">#f44336</color>
|
||||
<color name="red">#e53935</color>
|
||||
|
||||
@@ -136,9 +136,6 @@
|
||||
<bool name="autofill_auto_search_default" translatable="false">true</bool>
|
||||
<string name="autofill_application_id_blocklist_key" translatable="false">autofill_application_id_blocklist_key</string>
|
||||
<string-array name="autofill_application_id_blocklist_default">
|
||||
<item translatable="false">com.kunzisoft.keepass.libre</item>
|
||||
<item translatable="false">com.kunzisoft.keepass.free</item>
|
||||
<item translatable="false">com.kunzisoft.keepass.pro</item>
|
||||
</string-array>
|
||||
<string name="autofill_web_domain_blocklist_key" translatable="false">autofill_web_domain_blocklist_key</string>
|
||||
<string-array name="autofill_web_domain_blocklist_default">
|
||||
|
||||
@@ -388,6 +388,8 @@
|
||||
<string name="autofill_application_id_blocklist_summary">Blocklist that prevents auto filling of apps</string>
|
||||
<string name="autofill_web_domain_blocklist_title">Web domain blocklist</string>
|
||||
<string name="autofill_web_domain_blocklist_summary">Blocklist that prevents auto filling of web domains</string>
|
||||
<string name="autofill_block">Block autofill</string>
|
||||
<string name="autofill_block_restart">Restart the app containing the form to activate the blocking.</string>
|
||||
<string name="allow_no_password_title">Allow no master key</string>
|
||||
<string name="allow_no_password_summary">Enable the \"Open\" button if no credentials are selected</string>
|
||||
<string name="delete_entered_password_title">Delete password</string>
|
||||
|
||||
@@ -30,12 +30,13 @@
|
||||
<item name="android:textColorHintInverse">@color/green_light</item>
|
||||
<item name="android:windowBackground">@color/background_dark</item>
|
||||
<item name="toolbarAppearance">@style/KeepassDXStyle.Toolbar.Black</item>
|
||||
<item name="toolbarBottomAppearance">@style/KeepassDXStyle.Toolbar.Black</item>
|
||||
<item name="specialToolbarAppearance">@style/KeepassDXStyle.Toolbar.Special.Black</item>
|
||||
<item name="actionToolbarAppearance">@style/KeepassDXStyle.Toolbar.Black</item>
|
||||
<item name="android:alertDialogTheme">@style/KeepassDXStyle.Black.Dialog</item>
|
||||
<item name="alertDialogTheme">@style/KeepassDXStyle.Black.Dialog</item>
|
||||
<item name="actionModeStyle">@style/KeepassDXStyle.ActionMode.Dark</item>
|
||||
</style>
|
||||
<!-- Toolbar Style Black Green -->
|
||||
<!-- Toolbar Style Black -->
|
||||
<style name="KeepassDXStyle.Toolbar.Black" parent="KeepassDXStyle.Black">
|
||||
<item name="colorControlNormal">@color/colorTextInverse</item>
|
||||
<item name="android:textColorPrimary">@color/colorTextInverse</item>
|
||||
@@ -44,6 +45,11 @@
|
||||
<item name="android:textColorHint">@color/green_lighter</item>
|
||||
<item name="android:tint">@color/colorTextInverse</item>
|
||||
</style>
|
||||
<!-- Special Toolbar Black -->
|
||||
<style name="KeepassDXStyle.Toolbar.Special.Black" parent="KeepassDXStyle.Toolbar.Black">
|
||||
<item name="android:background">@color/black</item>
|
||||
<item name="background">@color/black</item>
|
||||
</style>
|
||||
<!-- Contextual Action Bar Dark -->
|
||||
<style name="KeepassDXStyle.ActionMode.Black" parent="@style/Widget.AppCompat.ActionMode">
|
||||
<item name="background">@color/dark</item>
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
<item name="android:textColorHintInverse">@color/blue_lighter</item>
|
||||
<item name="android:windowBackground">@color/background_light</item>
|
||||
<item name="toolbarAppearance">@style/KeepassDXStyle.Toolbar.Blue</item>
|
||||
<item name="toolbarBottomAppearance">@style/KeepassDXStyle.Toolbar.Bottom.Blue</item>
|
||||
<item name="specialToolbarAppearance">@style/KeepassDXStyle.Toolbar.Special.Blue</item>
|
||||
<item name="actionToolbarAppearance">@style/KeepassDXStyle.Toolbar.Action.Blue</item>
|
||||
<item name="actionModeStyle">@style/KeepassDXStyle.ActionMode.Blue</item>
|
||||
</style>
|
||||
<!-- Toolbar Style Blue -->
|
||||
@@ -42,7 +43,14 @@
|
||||
<item name="android:textColorHint">@color/blue_lighter</item>
|
||||
<item name="android:tint">@color/colorTextInverse</item>
|
||||
</style>
|
||||
<style name="KeepassDXStyle.Toolbar.Bottom.Blue" parent="KeepassDXStyle.Toolbar.Blue">
|
||||
<!-- Special Toolbar Blue -->
|
||||
<style name="KeepassDXStyle.Toolbar.Special.Blue" parent="KeepassDXStyle.Toolbar.Blue">
|
||||
<item name="actionMenuTextColor">@color/colorTextInverse</item>
|
||||
<item name="android:background">@color/blue_dark</item>
|
||||
<item name="background">@color/blue_dark</item>
|
||||
</style>
|
||||
<!-- Action Toolbar Blue -->
|
||||
<style name="KeepassDXStyle.Toolbar.Action.Blue" parent="KeepassDXStyle.Toolbar.Blue">
|
||||
<item name="actionMenuTextColor">@color/colorTextInverse</item>
|
||||
</style>
|
||||
<!-- Contextual Action Bar Blue -->
|
||||
|
||||
@@ -22,14 +22,15 @@
|
||||
<style name="KeepassDXStyle.Dark" parent="KeepassDXStyle.Night.v21" >
|
||||
<item name="colorPrimary">#212121</item>
|
||||
<item name="colorPrimaryDark">@color/dark</item>
|
||||
<item name="colorAccent">#2c7a96</item>
|
||||
<item name="colorAccentLight">#33b5e5</item>
|
||||
<item name="colorControlActivated">#33b5e5</item>
|
||||
<item name="android:textColorPrimary">#33b5e5</item>
|
||||
<item name="android:textColorHintInverse">#33b5e5</item>
|
||||
<item name="colorAccent">@color/cyan</item>
|
||||
<item name="colorAccentLight">@color/cyan_lighter</item>
|
||||
<item name="colorControlActivated">@color/cyan_lighter</item>
|
||||
<item name="android:textColorPrimary">@color/cyan_lighter</item>
|
||||
<item name="android:textColorHintInverse">@color/cyan_lighter</item>
|
||||
<item name="android:windowBackground">@color/background_dark</item>
|
||||
<item name="toolbarAppearance">@style/KeepassDXStyle.Toolbar.Dark</item>
|
||||
<item name="toolbarBottomAppearance">@style/KeepassDXStyle.Toolbar.Dark</item>
|
||||
<item name="specialToolbarAppearance">@style/KeepassDXStyle.Toolbar.Special.Dark</item>
|
||||
<item name="actionToolbarAppearance">@style/KeepassDXStyle.Toolbar.Dark</item>
|
||||
<item name="android:alertDialogTheme">@style/KeepassDXStyle.Dark.Dialog</item>
|
||||
<item name="alertDialogTheme">@style/KeepassDXStyle.Dark.Dialog</item>
|
||||
<item name="actionModeStyle">@style/KeepassDXStyle.ActionMode.Dark</item>
|
||||
@@ -41,6 +42,11 @@
|
||||
<item name="android:textColorSecondary">@color/colorTextSecondary</item>
|
||||
<item name="android:tint">@color/colorTextInverse</item>
|
||||
</style>
|
||||
<!-- Special Toolbar Dark -->
|
||||
<style name="KeepassDXStyle.Toolbar.Special.Dark" parent="KeepassDXStyle.Toolbar.Dark">
|
||||
<item name="android:background">@color/dark</item>
|
||||
<item name="background">@color/dark</item>
|
||||
</style>
|
||||
<!-- Contextual Action Bar Dark -->
|
||||
<style name="KeepassDXStyle.ActionMode.Dark" parent="@style/Widget.AppCompat.ActionMode">
|
||||
<item name="background">@color/dark</item>
|
||||
@@ -48,6 +54,6 @@
|
||||
<!-- Dialog -->
|
||||
<style name="KeepassDXStyle.Dark.Dialog" parent="KeepassDXStyle.Night.Dialog">
|
||||
<item name="colorAccent">#fefefe</item>
|
||||
<item name="android:textColorPrimary">#33b5e5</item>
|
||||
<item name="android:textColorPrimary">@color/cyan_lighter</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -29,7 +29,8 @@
|
||||
<item name="android:textColorHintInverse">@color/purple_lighter</item>
|
||||
<item name="android:windowBackground">@color/background_purple</item>
|
||||
<item name="toolbarAppearance">@style/KeepassDXStyle.Toolbar.Purple</item>
|
||||
<item name="toolbarBottomAppearance">@style/KeepassDXStyle.Toolbar.Bottom.Purple</item>
|
||||
<item name="specialToolbarAppearance">@style/KeepassDXStyle.Toolbar.Special.Purple</item>
|
||||
<item name="actionToolbarAppearance">@style/KeepassDXStyle.Toolbar.Action.Purple</item>
|
||||
<item name="actionModeStyle">@style/KeepassDXStyle.ActionMode.Purple</item>
|
||||
</style>
|
||||
<!-- Toolbar Style Purple -->
|
||||
@@ -42,7 +43,13 @@
|
||||
<item name="android:textColorHint">@color/purple_lighter</item>
|
||||
<item name="android:tint">@color/colorTextInverse</item>
|
||||
</style>
|
||||
<style name="KeepassDXStyle.Toolbar.Bottom.Purple" parent="KeepassDXStyle.Toolbar.Purple">
|
||||
<!-- Special Toolbar Purple -->
|
||||
<style name="KeepassDXStyle.Toolbar.Special.Purple" parent="KeepassDXStyle.Toolbar.Purple">
|
||||
<item name="android:background">@color/purple_dark</item>
|
||||
<item name="background">@color/purple_dark</item>
|
||||
</style>
|
||||
<!-- Action Toolbar Purple -->
|
||||
<style name="KeepassDXStyle.Toolbar.Action.Purple" parent="KeepassDXStyle.Toolbar.Purple">
|
||||
<item name="actionMenuTextColor">@color/colorTextInverse</item>
|
||||
</style>
|
||||
<!-- Contextual Action Bar Purple -->
|
||||
|
||||
@@ -29,7 +29,8 @@
|
||||
<item name="android:textColorHintInverse">@color/red_lighter</item>
|
||||
<item name="android:windowBackground">@color/background_night</item>
|
||||
<item name="toolbarAppearance">@style/KeepassDXStyle.Toolbar.Red</item>
|
||||
<item name="toolbarBottomAppearance">@style/KeepassDXStyle.Toolbar.Red</item>
|
||||
<item name="specialToolbarAppearance">@style/KeepassDXStyle.Toolbar.Special.Red</item>
|
||||
<item name="actionToolbarAppearance">@style/KeepassDXStyle.Toolbar.Red</item>
|
||||
<item name="actionModeStyle">@style/KeepassDXStyle.ActionMode.Red</item>
|
||||
</style>
|
||||
<!-- Toolbar Style Red -->
|
||||
@@ -42,6 +43,11 @@
|
||||
<item name="android:textColorHint">@color/red_lighter</item>
|
||||
<item name="android:tint">@color/colorTextInverse</item>
|
||||
</style>
|
||||
<!-- Special Toolbar Red -->
|
||||
<style name="KeepassDXStyle.Toolbar.Special.Red" parent="KeepassDXStyle.Toolbar.Red">
|
||||
<item name="android:background">@color/red_dark</item>
|
||||
<item name="background">@color/red_dark</item>
|
||||
</style>
|
||||
<!-- Contextual Action Bar Red -->
|
||||
<style name="KeepassDXStyle.ActionMode.Red" parent="@style/Widget.AppCompat.ActionMode">
|
||||
<item name="background">@color/orange</item>
|
||||
|
||||
@@ -74,7 +74,8 @@
|
||||
<!-- Toolbar -->
|
||||
<item name="toolbarAppearance">@style/KeepassDXStyle.Toolbar.Light</item>
|
||||
<item name="toolbarPopupAppearance">@style/KeepassDXStyle.Light.Toolbar.Popup</item>
|
||||
<item name="toolbarBottomAppearance">@style/KeepassDXStyle.Toolbar.Night</item>
|
||||
<item name="specialToolbarAppearance">@style/KeepassDXStyle.Toolbar.Special.Light</item>
|
||||
<item name="actionToolbarAppearance">@style/KeepassDXStyle.Toolbar.Light</item>
|
||||
<item name="actionModeStyle">@style/KeepassDXStyle.ActionMode</item>
|
||||
<!-- CollapsingToolbarLayout -->
|
||||
<item name="expandedTitleTextAppearance">@style/KeepassDXStyle.Expanded.Title</item>
|
||||
@@ -126,7 +127,8 @@
|
||||
<!-- Toolbar -->
|
||||
<item name="toolbarAppearance">@style/KeepassDXStyle.Toolbar.Night</item>
|
||||
<item name="toolbarPopupAppearance">@style/KeepassDXStyle.Night.Toolbar.Popup</item>
|
||||
<item name="toolbarBottomAppearance">@style/KeepassDXStyle.Toolbar.Night</item>
|
||||
<item name="specialToolbarAppearance">@style/KeepassDXStyle.Toolbar.Special.Night</item>
|
||||
<item name="actionToolbarAppearance">@style/KeepassDXStyle.Toolbar.Night</item>
|
||||
<item name="actionModeStyle">@style/KeepassDXStyle.ActionMode</item>
|
||||
<!-- CollapsingToolbarLayout -->
|
||||
<item name="expandedTitleTextAppearance">@style/KeepassDXStyle.Expanded.Title</item>
|
||||
@@ -175,8 +177,21 @@
|
||||
<item name="android:tint">@color/colorTextInverse</item>
|
||||
</style>
|
||||
|
||||
<!-- Special Toolbar Light Style -->
|
||||
<style name="KeepassDXStyle.Toolbar.Special.Light" parent="KeepassDXStyle.Toolbar.Light">
|
||||
<item name="android:background">@color/green_dark</item>
|
||||
<item name="background">@color/green_dark</item>
|
||||
</style>
|
||||
|
||||
<!-- Special Toolbar Night Style -->
|
||||
<style name="KeepassDXStyle.Toolbar.Special.Night" parent="KeepassDXStyle.Toolbar.Night">
|
||||
<item name="android:background">@color/green_dark</item>
|
||||
<item name="background">@color/green_dark</item>
|
||||
</style>
|
||||
|
||||
<!-- Contextual Action Bar -->
|
||||
<style name="KeepassDXStyle.ActionMode" parent="@style/Widget.AppCompat.ActionMode">
|
||||
<item name="android:background">@color/orange</item>
|
||||
<item name="background">@color/orange</item>
|
||||
</style>
|
||||
|
||||
@@ -257,7 +272,7 @@
|
||||
<item name="android:textColor">?android:attr/textColorPrimary</item>
|
||||
<item name="android:textSize">20sp</item>
|
||||
</style>
|
||||
<style name="KeepassDXStyle.TextAppearance.TinyText" parent="KeepassDXStyle.TextAppearance">
|
||||
<style name="KeepassDXStyle.TextAppearance.Tiny" parent="KeepassDXStyle.TextAppearance">
|
||||
<item name="android:textSize">12sp</item>
|
||||
</style>
|
||||
<style name="KeepassDXStyle.TextAppearance.WarningTextStyle" parent="KeepassDXStyle.TextAppearance">
|
||||
@@ -291,6 +306,14 @@
|
||||
<item name="android:tint">@color/group_subtitle_color</item>
|
||||
</style>
|
||||
|
||||
<!-- Special Toolbar text titlé -->
|
||||
<style name="KeepassDXStyle.TextAppearance.Toolbar.Special.Title" parent="KeepassDXStyle.TextAppearance.Small">
|
||||
<item name="android:textColor">?attr/colorAccent</item>
|
||||
</style>
|
||||
<style name="KeepassDXStyle.TextAppearance.Toolbar.Special.SubTitle" parent="KeepassDXStyle.TextAppearance.Tiny">
|
||||
<item name="android:textColor">@color/colorTextInverse</item>
|
||||
</style>
|
||||
|
||||
<!-- Button Style -->
|
||||
<style name="KeepassDXStyle.v21.Button" parent="Base.TextAppearance.AppCompat.Button">
|
||||
<item name="android:gravity">center</item>
|
||||
|
||||
Reference in New Issue
Block a user