Use DatabaseTaskProvider to retrieve database from service

This commit is contained in:
J-Jamet
2021-08-09 17:00:34 +02:00
parent bcd5b024f0
commit 5721bca5a3
9 changed files with 142 additions and 79 deletions

View File

@@ -105,11 +105,9 @@ class AutofillLauncherActivity : DatabaseActivity() {
SearchHelper.checkAutoSearchInfo(this,
database,
searchInfo,
{ items ->
{ openedDatabase, items ->
// Items found
database?.let {
AutofillHelper.buildResponseAndSetResult(this, database, items)
}
AutofillHelper.buildResponseAndSetResult(this, openedDatabase, items)
finish()
},
{
@@ -144,7 +142,7 @@ class AutofillLauncherActivity : DatabaseActivity() {
SearchHelper.checkAutoSearchInfo(this,
database,
searchInfo,
{ _ ->
{ _, _ ->
if (!readOnly) {
// Show the database UI to select the entry
GroupActivity.launchForRegistration(this,

View File

@@ -95,7 +95,7 @@ class EntrySelectionLauncherActivity : DatabaseActivity() {
SearchHelper.checkAutoSearchInfo(this,
database,
searchInfo,
{ items ->
{ _, items ->
// Items found
if (searchInfo.otpString != null) {
if (!readOnly) {

View File

@@ -600,9 +600,9 @@ class GroupActivity : LockingActivity(),
SearchHelper.checkAutoSearchInfo(this,
database,
searchInfo,
{ _ ->
{ openedDatabase, _ ->
// Item in search, don't save
entrySelectedForKeyboardSelection(database, entryVersioned)
entrySelectedForKeyboardSelection(openedDatabase, entryVersioned)
},
{
// Item not found, save it if required
@@ -1302,7 +1302,7 @@ class GroupActivity : LockingActivity(),
SearchHelper.checkAutoSearchInfo(activity,
database,
searchInfo,
{ _ ->
{ _, _ ->
// Response is build
GroupActivity.launchForSearchResult(activity,
readOnly,
@@ -1349,7 +1349,7 @@ class GroupActivity : LockingActivity(),
SearchHelper.checkAutoSearchInfo(activity,
database,
searchInfo,
{ items ->
{ _, items ->
// Response is build
if (items.size == 1) {
populateKeyboardAndMoveAppToBackground(activity,
@@ -1384,9 +1384,9 @@ class GroupActivity : LockingActivity(),
SearchHelper.checkAutoSearchInfo(activity,
database,
searchInfo,
{ items ->
{ openedDatabase, items ->
// Response is build
AutofillHelper.buildResponseAndSetResult(activity, database, items)
AutofillHelper.buildResponseAndSetResult(activity, openedDatabase, items)
onValidateSpecialMode()
},
{
@@ -1412,7 +1412,7 @@ class GroupActivity : LockingActivity(),
SearchHelper.checkAutoSearchInfo(activity,
database,
registerInfo?.searchInfo,
{ _ ->
{ _, _ ->
// No auto search, it's a registration
GroupActivity.launchForRegistration(activity,
registerInfo)

View File

@@ -38,7 +38,7 @@ class MagikeyboardLauncherActivity : DatabaseActivity() {
SearchHelper.checkAutoSearchInfo(this,
database,
null,
{
{ _, _ ->
// Not called
// if items found directly returns before calling this activity
},

View File

@@ -36,6 +36,7 @@ import androidx.autofill.inline.UiVersions
import androidx.autofill.inline.v1.InlineSuggestionUi
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.AutofillLauncherActivity
import com.kunzisoft.keepass.database.action.DatabaseTaskProvider
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.database.search.SearchHelper
import com.kunzisoft.keepass.model.CreditCard
@@ -50,18 +51,32 @@ import java.util.concurrent.atomic.AtomicBoolean
@RequiresApi(api = Build.VERSION_CODES.O)
class KeeAutofillService : AutofillService() {
var applicationIdBlocklist: Set<String>? = null
var webDomainBlocklist: Set<String>? = null
var askToSaveData: Boolean = false
var autofillInlineSuggestionsEnabled: Boolean = false
private var mDatabaseTaskProvider: DatabaseTaskProvider? = null
private var mDatabase: Database? = null
private var applicationIdBlocklist: Set<String>? = null
private var webDomainBlocklist: Set<String>? = null
private var askToSaveData: Boolean = false
private var autofillInlineSuggestionsEnabled: Boolean = false
private var mLock = AtomicBoolean()
override fun onCreate() {
super.onCreate()
mDatabaseTaskProvider = DatabaseTaskProvider(this)
mDatabaseTaskProvider?.registerProgressTask()
mDatabaseTaskProvider?.onDatabaseRetrieved = { database ->
this.mDatabase = database
}
getPreferences()
}
override fun onDestroy() {
mDatabaseTaskProvider?.unregisterProgressTask()
super.onDestroy()
}
private fun getPreferences() {
applicationIdBlocklist = PreferencesUtil.applicationIdBlocklist(this)
webDomainBlocklist = PreferencesUtil.webDomainBlocklist(this)
@@ -98,9 +113,7 @@ class KeeAutofillService : AutofillService() {
} else {
null
}
// TODO database
Database.getInstance()?.let { database ->
launchSelection(database,
launchSelection(mDatabase,
searchInfo,
parseResult,
inlineSuggestionsRequest,
@@ -110,9 +123,8 @@ class KeeAutofillService : AutofillService() {
}
}
}
}
private fun launchSelection(database: Database,
private fun launchSelection(database: Database?,
searchInfo: SearchInfo,
parseResult: StructureParser.Result,
inlineSuggestionsRequest: InlineSuggestionsRequest?,
@@ -120,9 +132,9 @@ class KeeAutofillService : AutofillService() {
SearchHelper.checkAutoSearchInfo(this,
database,
searchInfo,
{ items ->
{ openedDatabase, items ->
callback.onSuccess(
AutofillHelper.buildResponse(this, database,
AutofillHelper.buildResponse(this, openedDatabase,
items, parseResult, inlineSuggestionsRequest)
)
},

View File

@@ -19,6 +19,7 @@
*/
package com.kunzisoft.keepass.database.action
import android.app.Service
import android.content.*
import android.content.Context.*
import android.net.Uri
@@ -83,7 +84,15 @@ import kotlinx.coroutines.launch
import java.util.*
import kotlin.collections.ArrayList
class DatabaseTaskProvider(private val activity: FragmentActivity) {
/**
* Utility class to connect an activity or a service to the DatabaseTaskNotificationService,
* Useful to retrieve a database instance and sending tasks commands
*/
class DatabaseTaskProvider {
private var activity: FragmentActivity? = null
private var service: Service? = null
private var context: Context
var onDatabaseRetrieved: ((database: Database?) -> Unit)? = null
@@ -91,7 +100,7 @@ class DatabaseTaskProvider(private val activity: FragmentActivity) {
actionTask: String,
result: ActionRunnable.Result) -> Unit)? = null
private var intentDatabaseTask = Intent(activity.applicationContext, DatabaseTaskNotificationService::class.java)
private var intentDatabaseTask: Intent
private var databaseTaskBroadcastReceiver: BroadcastReceiver? = null
private var mBinder: DatabaseTaskNotificationService.ActionTaskBinder? = null
@@ -101,6 +110,20 @@ class DatabaseTaskProvider(private val activity: FragmentActivity) {
private var progressTaskDialogFragment: ProgressTaskDialogFragment? = null
private var databaseChangedDialogFragment: DatabaseChangedDialogFragment? = null
constructor(activity: FragmentActivity) {
this.activity = activity
this.context = activity
this.intentDatabaseTask = Intent(activity.applicationContext,
DatabaseTaskNotificationService::class.java)
}
constructor(service: Service) {
this.service = service
this.context = service
this.intentDatabaseTask = Intent(service.applicationContext,
DatabaseTaskNotificationService::class.java)
}
private val actionTaskListener = object: DatabaseTaskNotificationService.ActionTaskListener {
override fun onStartAction(database: Database, titleId: Int?, messageId: Int?, warningId: Int?) {
startDialog(titleId, messageId, warningId)
@@ -126,18 +149,21 @@ class DatabaseTaskProvider(private val activity: FragmentActivity) {
private var databaseInfoListener = object: DatabaseTaskNotificationService.DatabaseInfoListener {
override fun onDatabaseInfoChanged(previousDatabaseInfo: SnapFileDatabaseInfo,
newDatabaseInfo: SnapFileDatabaseInfo) {
activity?.let { activity ->
activity.lifecycleScope.launch {
if (databaseChangedDialogFragment == null) {
databaseChangedDialogFragment = activity.supportFragmentManager
.findFragmentByTag(DATABASE_CHANGED_DIALOG_TAG) as DatabaseChangedDialogFragment?
databaseChangedDialogFragment?.actionDatabaseListener = mActionDatabaseListener
databaseChangedDialogFragment?.actionDatabaseListener =
mActionDatabaseListener
}
if (progressTaskDialogFragment == null) {
databaseChangedDialogFragment = DatabaseChangedDialogFragment.getInstance(
previousDatabaseInfo,
newDatabaseInfo
)
databaseChangedDialogFragment?.actionDatabaseListener = mActionDatabaseListener
databaseChangedDialogFragment?.actionDatabaseListener =
mActionDatabaseListener
databaseChangedDialogFragment?.show(
activity.supportFragmentManager,
DATABASE_CHANGED_DIALOG_TAG
@@ -146,6 +172,7 @@ class DatabaseTaskProvider(private val activity: FragmentActivity) {
}
}
}
}
private var databaseListener = object: DatabaseTaskNotificationService.DatabaseListener {
override fun onDatabaseRetrieved(database: Database?) {
@@ -156,6 +183,7 @@ class DatabaseTaskProvider(private val activity: FragmentActivity) {
private fun startDialog(titleId: Int? = null,
messageId: Int? = null,
warningId: Int? = null) {
activity?.let { activity ->
activity.lifecycleScope.launch {
if (progressTaskDialogFragment == null) {
progressTaskDialogFragment = activity.supportFragmentManager
@@ -171,6 +199,7 @@ class DatabaseTaskProvider(private val activity: FragmentActivity) {
updateDialog(titleId, messageId, warningId)
}
}
}
private fun updateDialog(titleId: Int?, messageId: Int?, warningId: Int?) {
progressTaskDialogFragment?.apply {
@@ -218,7 +247,7 @@ class DatabaseTaskProvider(private val activity: FragmentActivity) {
private fun bindService() {
initServiceConnection()
serviceConnection?.let {
activity.bindService(intentDatabaseTask, it, BIND_AUTO_CREATE or BIND_NOT_FOREGROUND or BIND_ABOVE_CLIENT)
context.bindService(intentDatabaseTask, it, BIND_AUTO_CREATE or BIND_NOT_FOREGROUND or BIND_ABOVE_CLIENT)
}
}
@@ -227,7 +256,7 @@ class DatabaseTaskProvider(private val activity: FragmentActivity) {
*/
private fun unBindService() {
serviceConnection?.let {
activity.unbindService(it)
context.unbindService(it)
}
serviceConnection = null
}
@@ -255,7 +284,7 @@ class DatabaseTaskProvider(private val activity: FragmentActivity) {
}
}
}
activity.registerReceiver(databaseTaskBroadcastReceiver,
context.registerReceiver(databaseTaskBroadcastReceiver,
IntentFilter().apply {
addAction(DATABASE_START_TASK_ACTION)
addAction(DATABASE_STOP_TASK_ACTION)
@@ -277,7 +306,7 @@ class DatabaseTaskProvider(private val activity: FragmentActivity) {
unBindService()
try {
activity.unregisterReceiver(databaseTaskBroadcastReceiver)
context.unregisterReceiver(databaseTaskBroadcastReceiver)
} catch (e: IllegalArgumentException) {
// If receiver not register, do nothing
}
@@ -288,7 +317,7 @@ class DatabaseTaskProvider(private val activity: FragmentActivity) {
if (bundle != null)
intentDatabaseTask.putExtras(bundle)
intentDatabaseTask.action = actionTask
activity.startService(intentDatabaseTask)
context.startService(intentDatabaseTask)
} catch (e: Exception) {
Log.e(TAG, "Unable to perform database action", e)
Toast.makeText(activity, R.string.error_start_database_action, Toast.LENGTH_LONG).show()

View File

@@ -94,8 +94,9 @@ class SearchHelper {
fun checkAutoSearchInfo(context: Context,
database: Database?,
searchInfo: SearchInfo?,
onItemsFound: (items: List<EntryInfo>) -> Unit,
onItemNotFound: () -> Unit,
onItemsFound: (openedDatabase: Database,
items: List<EntryInfo>) -> Unit,
onItemNotFound: (openedDatabase: Database) -> Unit,
onDatabaseClosed: () -> Unit) {
if (database == null || !database.loaded) {
onDatabaseClosed.invoke()
@@ -112,13 +113,13 @@ class SearchHelper {
)?.let { searchGroup ->
if (searchGroup.getNumberOfChildEntries() > 0) {
searchWithoutUI = true
onItemsFound.invoke(
onItemsFound.invoke(database,
searchGroup.getChildEntriesInfo(database))
}
}
}
if (!searchWithoutUI) {
onItemNotFound.invoke()
onItemNotFound.invoke(database)
}
}
}

View File

@@ -38,16 +38,20 @@ import android.widget.TextView
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.activities.MagikeyboardLauncherActivity
import com.kunzisoft.keepass.adapters.FieldsAdapter
import com.kunzisoft.keepass.database.action.DatabaseTaskProvider
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.model.EntryInfo
import com.kunzisoft.keepass.database.element.Field
import com.kunzisoft.keepass.services.KeyboardEntryNotificationService
import com.kunzisoft.keepass.model.EntryInfo
import com.kunzisoft.keepass.otp.OtpEntryFields.OTP_TOKEN_FIELD
import com.kunzisoft.keepass.services.KeyboardEntryNotificationService
import com.kunzisoft.keepass.settings.PreferencesUtil
import com.kunzisoft.keepass.utils.*
class MagikeyboardService : InputMethodService(), KeyboardView.OnKeyboardActionListener {
private var mDatabaseTaskProvider: DatabaseTaskProvider? = null
private var mDatabase: Database? = null
private var keyboardView: KeyboardView? = null
private var entryText: TextView? = null
private var keyboard: Keyboard? = null
@@ -61,6 +65,11 @@ class MagikeyboardService : InputMethodService(), KeyboardView.OnKeyboardActionL
override fun onCreate() {
super.onCreate()
mDatabaseTaskProvider = DatabaseTaskProvider(this)
mDatabaseTaskProvider?.registerProgressTask()
mDatabaseTaskProvider?.onDatabaseRetrieved = { database ->
this.mDatabase = database
}
// Remove the entry and lock the keyboard when the lock signal is receive
lockReceiver = LockReceiver {
removeEntryInfo()
@@ -111,11 +120,10 @@ class MagikeyboardService : InputMethodService(), KeyboardView.OnKeyboardActionL
// Remove entry info if the database is not loaded
// or if entry info timestamp is before database loaded timestamp
// TODO Database
val database = Database.getInstance()
val databaseTime = database.loadTimestamp
val databaseTime = mDatabase?.loadTimestamp
val entryTime = entryInfoTimestamp
if (!database.loaded
if (mDatabase == null
|| mDatabase?.loaded != true
|| databaseTime == null
|| entryTime == null
|| entryTime < databaseTime) {
@@ -324,6 +332,7 @@ class MagikeyboardService : InputMethodService(), KeyboardView.OnKeyboardActionL
override fun onDestroy() {
dismissCustomKeys()
unregisterLockReceiver(lockReceiver)
mDatabaseTaskProvider?.unregisterProgressTask()
super.onDestroy()
}

View File

@@ -27,6 +27,7 @@ import android.os.Binder
import android.os.IBinder
import android.util.Log
import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.action.DatabaseTaskProvider
import com.kunzisoft.keepass.database.element.Attachment
import com.kunzisoft.keepass.database.element.Database
import com.kunzisoft.keepass.model.AttachmentState
@@ -41,6 +42,9 @@ import java.util.concurrent.CopyOnWriteArrayList
class AttachmentFileNotificationService: LockNotificationService() {
private var mDatabaseTaskProvider: DatabaseTaskProvider? = null
private var mDatabase: Database? = null
override val notificationId: Int = 10000
private val attachmentNotificationList = CopyOnWriteArrayList<AttachmentNotification>()
@@ -80,6 +84,16 @@ class AttachmentFileNotificationService: LockNotificationService() {
}
}
override fun onCreate() {
super.onCreate()
mDatabaseTaskProvider = DatabaseTaskProvider(this)
mDatabaseTaskProvider?.registerProgressTask()
mDatabaseTaskProvider?.onDatabaseRetrieved = { database ->
this.mDatabase = database
}
}
interface ActionTaskListener {
fun onAttachmentAction(fileUri: Uri, entryAttachmentState: EntryAttachmentState)
}
@@ -247,6 +261,7 @@ class AttachmentFileNotificationService: LockNotificationService() {
notificationManager?.cancel(attachmentNotification.notificationId)
}
attachmentNotificationList.clear()
mDatabaseTaskProvider?.unregisterProgressTask()
super.onDestroy()
}
@@ -287,8 +302,7 @@ class AttachmentFileNotificationService: LockNotificationService() {
// Add action to the list on start
attachmentNotificationList.add(attachmentNotification)
// TODO Database
Database.getInstance()?.let { database ->
mDatabase?.let { database ->
mainScope.launch {
AttachmentFileAction(attachmentNotification,
database,