Fix dialog update

This commit is contained in:
J-Jamet
2019-10-16 15:31:07 +02:00
parent a21de3b892
commit 2637788429
4 changed files with 162 additions and 54 deletions

View File

@@ -1,12 +1,10 @@
package com.kunzisoft.keepass.database.action package com.kunzisoft.keepass.database.action
import android.content.BroadcastReceiver import android.content.*
import android.content.Context import android.content.Context.BIND_ABOVE_CLIENT
import android.content.Intent import android.content.Context.BIND_NOT_FOREGROUND
import android.content.IntentFilter
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.*
import android.os.Bundle
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.database.element.* import com.kunzisoft.keepass.database.element.*
@@ -23,38 +21,102 @@ import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Compa
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_UPDATE_ENTRY_TASK import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_UPDATE_ENTRY_TASK
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_UPDATE_GROUP_TASK import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_DATABASE_UPDATE_GROUP_TASK
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_TASK_KEY import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.ACTION_TASK_KEY
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.CHECK_ACTION
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.DATABASE_TASK_MESSAGE_KEY import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.DATABASE_TASK_MESSAGE_KEY
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.DATABASE_TASK_SUBTITLE_KEY import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.DATABASE_TASK_WARNING_KEY
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.DATABASE_TASK_TITLE_KEY import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.DATABASE_TASK_TITLE_KEY
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.RESULT_KEY import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.RESULT_KEY
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.START_ACTION
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.STOP_ACTION
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.UPDATE_ACTION_ELEMENTS
import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.getBundleFromListNodes import com.kunzisoft.keepass.notifications.DatabaseTaskNotificationService.Companion.getBundleFromListNodes
import com.kunzisoft.keepass.tasks.ActionRunnable import com.kunzisoft.keepass.tasks.ActionRunnable
import com.kunzisoft.keepass.tasks.ProgressTaskDialogFragment import com.kunzisoft.keepass.tasks.ProgressTaskDialogFragment
import com.kunzisoft.keepass.tasks.ProgressTaskDialogFragment.Companion.UNDEFINED
import com.kunzisoft.keepass.timeout.TimeoutHelper import com.kunzisoft.keepass.timeout.TimeoutHelper
import com.kunzisoft.keepass.utils.DATABASE_CHECK_TASK_ACTION
import com.kunzisoft.keepass.utils.DATABASE_START_TASK_ACTION import com.kunzisoft.keepass.utils.DATABASE_START_TASK_ACTION
import com.kunzisoft.keepass.utils.DATABASE_STOP_TASK_ACTION import com.kunzisoft.keepass.utils.DATABASE_STOP_TASK_ACTION
import java.io.File import java.io.File
import java.util.* import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
class ProgressDialogThread(private val activity: FragmentActivity, class ProgressDialogThread(private val activity: FragmentActivity,
var onActionFinish: (actionTask: String, var onActionFinish: (actionTask: String,
result: ActionRunnable.Result) -> Unit) { result: ActionRunnable.Result) -> Unit) {
private var progressTaskDialogFragment: ProgressTaskDialogFragment? = null private var progressTaskDialogFragment: ProgressTaskDialogFragment? = null
private var databaseTaskBroadcastReceiver: BroadcastReceiver? = null
private var intentDatabaseTask = Intent(activity, DatabaseTaskNotificationService::class.java) private var intentDatabaseTask = Intent(activity, DatabaseTaskNotificationService::class.java)
private fun startDialog(intent: Intent) { private var databaseTaskBroadcastReceiver: BroadcastReceiver? = null
private var actionMessenger: Messenger? = null
private var serviceConnection = object: ServiceConnection {
override fun onServiceDisconnected(name: ComponentName?) {
actionMessenger = null
}
override fun onServiceConnected(name: ComponentName?, serviceBinder: IBinder?) {
actionMessenger = Messenger(serviceBinder)
try {
val message = Message.obtain(null, CHECK_ACTION)
message.replyTo = Messenger(ResponseHandler(activity, onActionFinish))
actionMessenger?.send(message)
} catch (e: RemoteException) {
e.printStackTrace()
}
}
}
private class ResponseHandler(private val activity: FragmentActivity,
var onActionFinish: (actionTask: String,
result: ActionRunnable.Result) -> Unit) : Handler() {
override fun handleMessage(message: Message) {
when (message.what) {
START_ACTION -> {
TimeoutHelper.temporarilyDisableTimeout()
ProgressTaskDialogFragment.start(activity,
ProgressTaskDialogFragment.build())
}
STOP_ACTION -> {
ProgressTaskDialogFragment.stop(activity)
TimeoutHelper.releaseTemporarilyDisableTimeoutAndLockIfTimeout(activity)
val dataBundle = message.data
if (dataBundle != null
&& dataBundle.containsKey(ACTION_TASK_KEY)
&& dataBundle.containsKey(RESULT_KEY))
onActionFinish.invoke(
dataBundle.getString(ACTION_TASK_KEY)!!,
ActionRunnable.Result.fromBundle(dataBundle.getBundle(RESULT_KEY)!!))
}
UPDATE_ACTION_ELEMENTS -> {
// TODO better implementation
val dataBundle = message.data
if (dataBundle != null) {
if (dataBundle.containsKey(DATABASE_TASK_TITLE_KEY))
ProgressTaskDialogFragment.updateTitle(activity,
message.data.getInt(DATABASE_TASK_TITLE_KEY))
if (dataBundle.containsKey(DATABASE_TASK_MESSAGE_KEY))
ProgressTaskDialogFragment.updateMessage(activity,
message.data.getInt(DATABASE_TASK_MESSAGE_KEY))
if (dataBundle.containsKey(DATABASE_TASK_WARNING_KEY))
ProgressTaskDialogFragment.updateWarning(activity,
message.data.getInt(DATABASE_TASK_WARNING_KEY))
}
}
}
}
}
private fun startDialog(intent: Intent? = null) {
TimeoutHelper.temporarilyDisableTimeout() TimeoutHelper.temporarilyDisableTimeout()
// Show the dialog // Show the dialog
progressTaskDialogFragment = ProgressTaskDialogFragment.build( val title = intent?.getIntExtra(DATABASE_TASK_TITLE_KEY, R.string.loading_database) ?: UNDEFINED
intent.getIntExtra(DATABASE_TASK_TITLE_KEY, R.string.loading_database), val subTitle = intent?.getIntExtra(DATABASE_TASK_WARNING_KEY, UNDEFINED) ?: UNDEFINED
intent.getIntExtra(DATABASE_TASK_SUBTITLE_KEY, ProgressTaskDialogFragment.UNDEFINED), val message = intent?.getIntExtra(DATABASE_TASK_MESSAGE_KEY, UNDEFINED) ?: UNDEFINED
intent.getIntExtra(DATABASE_TASK_MESSAGE_KEY, ProgressTaskDialogFragment.UNDEFINED)) progressTaskDialogFragment = ProgressTaskDialogFragment.build(title, subTitle, message)
ProgressTaskDialogFragment.start(activity, progressTaskDialogFragment!!) ProgressTaskDialogFragment.start(activity, progressTaskDialogFragment!!)
} }
@@ -62,7 +124,6 @@ class ProgressDialogThread(private val activity: FragmentActivity,
// Remove the progress task // Remove the progress task
ProgressTaskDialogFragment.stop(activity) ProgressTaskDialogFragment.stop(activity)
TimeoutHelper.releaseTemporarilyDisableTimeoutAndLockIfTimeout(activity) TimeoutHelper.releaseTemporarilyDisableTimeoutAndLockIfTimeout(activity)
activity.stopService(intentDatabaseTask)
if (intent != null if (intent != null
&& intent.hasExtra(ACTION_TASK_KEY) && intent.hasExtra(ACTION_TASK_KEY)
&& intent.hasExtra(RESULT_KEY)) && intent.hasExtra(RESULT_KEY))
@@ -97,10 +158,12 @@ class ProgressDialogThread(private val activity: FragmentActivity,
) )
// Check if a service is currently running // Check if a service is currently running
activity.sendBroadcast(Intent(DATABASE_CHECK_TASK_ACTION)) activity.bindService(intentDatabaseTask, serviceConnection, BIND_NOT_FOREGROUND or BIND_ABOVE_CLIENT)
} }
fun unregisterProgressTask() { fun unregisterProgressTask() {
activity.unbindService(serviceConnection)
activity.unregisterReceiver(databaseTaskBroadcastReceiver) activity.unregisterReceiver(databaseTaskBroadcastReceiver)
} }

View File

@@ -1,12 +1,8 @@
package com.kunzisoft.keepass.notifications package com.kunzisoft.keepass.notifications
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter
import android.net.Uri import android.net.Uri
import android.os.AsyncTask import android.os.*
import android.os.Bundle
import android.util.Log import android.util.Log
import com.kunzisoft.keepass.R import com.kunzisoft.keepass.R
import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction import com.kunzisoft.keepass.app.database.FileDatabaseHistoryAction
@@ -18,12 +14,12 @@ import com.kunzisoft.keepass.database.action.node.*
import com.kunzisoft.keepass.database.element.* import com.kunzisoft.keepass.database.element.*
import com.kunzisoft.keepass.tasks.ActionRunnable import com.kunzisoft.keepass.tasks.ActionRunnable
import com.kunzisoft.keepass.tasks.ProgressTaskUpdater import com.kunzisoft.keepass.tasks.ProgressTaskUpdater
import com.kunzisoft.keepass.utils.DATABASE_CHECK_TASK_ACTION
import com.kunzisoft.keepass.utils.DATABASE_START_TASK_ACTION import com.kunzisoft.keepass.utils.DATABASE_START_TASK_ACTION
import com.kunzisoft.keepass.utils.DATABASE_STOP_TASK_ACTION import com.kunzisoft.keepass.utils.DATABASE_STOP_TASK_ACTION
import java.io.File import java.io.File
import java.util.* import java.util.*
import kotlin.collections.ArrayList import kotlin.collections.ArrayList
import android.os.Bundle
class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdater { class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdater {
@@ -31,27 +27,44 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
private var actionRunnableAsyncTask: ActionRunnableAsyncTask? = null private var actionRunnableAsyncTask: ActionRunnableAsyncTask? = null
private var checkBroadcastReceiver: BroadcastReceiver? = null private var actionStatusHandler = ActionStatusHandler()
private var actionMessenger = Messenger(actionStatusHandler)
override fun onCreate() { private class ActionStatusHandler: Handler() {
super.onCreate() var titleId: Int? = null
var messageId: Int? = null
var warningId: Int? = null
checkBroadcastReceiver = object: BroadcastReceiver() { override fun handleMessage(message: Message?) {
override fun onReceive(context: Context?, intent: Intent?) { when (message?.what) {
sendBroadcast(Intent(DATABASE_START_TASK_ACTION)) CHECK_ACTION -> {
try {
// Incoming data
val response = Message.obtain(null, UPDATE_ACTION_ELEMENTS)
response.data = Bundle().apply {
titleId?.let {
putInt(DATABASE_TASK_TITLE_KEY, it)
}
messageId?.let {
putInt(DATABASE_TASK_MESSAGE_KEY, it)
}
warningId?.let {
putInt(DATABASE_TASK_WARNING_KEY, it)
}
}
message.replyTo?.send(response)
} catch (e: RemoteException) {
e.printStackTrace()
}
}
else -> super.handleMessage(message)
} }
} }
registerReceiver(checkBroadcastReceiver, IntentFilter().apply {
addAction(DATABASE_CHECK_TASK_ACTION)
}
)
} }
override fun onDestroy() { override fun onBind(intent: Intent): IBinder? {
unregisterReceiver(checkBroadcastReceiver) return actionMessenger.binder
super.onDestroy()
} }
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
@@ -72,13 +85,15 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
ACTION_DATABASE_LOAD_TASK -> R.string.loading_database ACTION_DATABASE_LOAD_TASK -> R.string.loading_database
else -> R.string.loading_database else -> R.string.loading_database
} }
val subtitleId: Int? = when (intent.action) {
else -> null
}
val messageId: Int? = when (intent.action) { val messageId: Int? = when (intent.action) {
ACTION_DATABASE_LOAD_TASK -> null ACTION_DATABASE_LOAD_TASK -> null
else -> R.string.do_not_kill_app else -> null
} }
val warningId: Int? =
if (intent.action == ACTION_DATABASE_LOAD_TASK)
null
else
R.string.do_not_kill_app
val actionRunnable: ActionRunnable? = when (intent.action) { val actionRunnable: ActionRunnable? = when (intent.action) {
ACTION_DATABASE_CREATE_TASK -> buildDatabaseCreateActionTask(intent) ACTION_DATABASE_CREATE_TASK -> buildDatabaseCreateActionTask(intent)
@@ -107,13 +122,16 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
ACTION_DATABASE_COPY_NODES_TASK, ACTION_DATABASE_COPY_NODES_TASK,
ACTION_DATABASE_MOVE_NODES_TASK, ACTION_DATABASE_MOVE_NODES_TASK,
ACTION_DATABASE_DELETE_NODES_TASK -> { ACTION_DATABASE_DELETE_NODES_TASK -> {
actionStatusHandler.titleId = titleId
actionStatusHandler.messageId = messageId
actionStatusHandler.warningId = warningId
newNotification(intent.getIntExtra(DATABASE_TASK_TITLE_KEY, titleId)) newNotification(intent.getIntExtra(DATABASE_TASK_TITLE_KEY, titleId))
actionRunnableAsyncTask = ActionRunnableAsyncTask(this, actionRunnableAsyncTask = ActionRunnableAsyncTask(this,
{ {
sendBroadcast(Intent(DATABASE_START_TASK_ACTION).apply { sendBroadcast(Intent(DATABASE_START_TASK_ACTION).apply {
putExtra(DATABASE_TASK_TITLE_KEY, titleId) putExtra(DATABASE_TASK_TITLE_KEY, titleId)
putExtra(DATABASE_TASK_SUBTITLE_KEY, subtitleId)
putExtra(DATABASE_TASK_MESSAGE_KEY, messageId) putExtra(DATABASE_TASK_MESSAGE_KEY, messageId)
putExtra(DATABASE_TASK_WARNING_KEY, warningId)
}) })
}, { result -> }, { result ->
@@ -121,6 +139,7 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
putExtra(ACTION_TASK_KEY, intent.action) putExtra(ACTION_TASK_KEY, intent.action)
putExtra(RESULT_KEY, result.toBundle()) putExtra(RESULT_KEY, result.toBundle())
}) })
stopSelf()
} }
) )
actionRunnable?.let { actionRunnableNotNull -> actionRunnable?.let { actionRunnableNotNull ->
@@ -412,9 +431,13 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
private val TAG = DatabaseTaskNotificationService::class.java.name private val TAG = DatabaseTaskNotificationService::class.java.name
const val START_ACTION = 42
const val STOP_ACTION = 43
const val CHECK_ACTION = 44
const val UPDATE_ACTION_ELEMENTS = 45
const val DATABASE_TASK_TITLE_KEY = "DATABASE_TASK_TITLE_KEY" const val DATABASE_TASK_TITLE_KEY = "DATABASE_TASK_TITLE_KEY"
const val DATABASE_TASK_SUBTITLE_KEY = "DATABASE_TASK_SUBTITLE_KEY"
const val DATABASE_TASK_MESSAGE_KEY = "DATABASE_TASK_MESSAGE_KEY" const val DATABASE_TASK_MESSAGE_KEY = "DATABASE_TASK_MESSAGE_KEY"
const val DATABASE_TASK_WARNING_KEY = "DATABASE_TASK_WARNING_KEY"
const val ACTION_DATABASE_CREATE_TASK = "ACTION_DATABASE_CREATE_TASK" const val ACTION_DATABASE_CREATE_TASK = "ACTION_DATABASE_CREATE_TASK"
const val ACTION_DATABASE_SAVE_TASK = "ACTION_DATABASE_SAVE_TASK" const val ACTION_DATABASE_SAVE_TASK = "ACTION_DATABASE_SAVE_TASK"

View File

@@ -110,12 +110,14 @@ open class ProgressTaskDialogFragment : DialogFragment(), ProgressTaskUpdater {
const val UNDEFINED = -1 const val UNDEFINED = -1
fun build(@StringRes titleId: Int, fun build(@StringRes titleId: Int? = null,
@StringRes messageId: Int? = null, @StringRes messageId: Int? = null,
@StringRes warningId: Int? = null): ProgressTaskDialogFragment { @StringRes warningId: Int? = null): ProgressTaskDialogFragment {
// Create an instance of the dialog fragment and show it // Create an instance of the dialog fragment and show it
val dialog = ProgressTaskDialogFragment() val dialog = ProgressTaskDialogFragment()
dialog.updateTitle(titleId) titleId?.let {
dialog.updateTitle(it)
}
messageId?.let { messageId?.let {
dialog.updateMessage(it) dialog.updateMessage(it)
} }
@@ -130,12 +132,34 @@ open class ProgressTaskDialogFragment : DialogFragment(), ProgressTaskUpdater {
dialog.show(activity.supportFragmentManager, PROGRESS_TASK_DIALOG_TAG) dialog.show(activity.supportFragmentManager, PROGRESS_TASK_DIALOG_TAG)
} }
fun stop(activity: FragmentActivity) { private fun retrieveProgressDialog(activity: FragmentActivity): ProgressTaskDialogFragment? {
val fragmentTask = activity.supportFragmentManager.findFragmentByTag(PROGRESS_TASK_DIALOG_TAG) return activity.supportFragmentManager
if (fragmentTask != null) { .findFragmentByTag(PROGRESS_TASK_DIALOG_TAG) as ProgressTaskDialogFragment?
val loadingDatabaseDialog = fragmentTask as ProgressTaskDialogFragment }
loadingDatabaseDialog.dismissAllowingStateLoss()
private fun retrieveAndShowProgressDialog(activity: FragmentActivity): ProgressTaskDialogFragment {
var dialog = retrieveProgressDialog(activity)
if (dialog == null) {
dialog = build()
start(activity, build())
} }
return dialog
}
fun stop(activity: FragmentActivity) {
retrieveProgressDialog(activity)?.dismissAllowingStateLoss()
}
fun updateTitle(activity: FragmentActivity, titleId: Int) {
retrieveAndShowProgressDialog(activity).updateTitle(titleId)
}
fun updateMessage(activity: FragmentActivity, messageId: Int) {
retrieveAndShowProgressDialog(activity).updateMessage(messageId)
}
fun updateWarning(activity: FragmentActivity, warningId: Int) {
retrieveAndShowProgressDialog(activity).updateWarning(warningId)
} }
} }
} }

View File

@@ -3,8 +3,6 @@ package com.kunzisoft.keepass.utils
const val DATABASE_START_TASK_ACTION = "com.kunzisoft.keepass.DATABASE_START_TASK_ACTION" const val DATABASE_START_TASK_ACTION = "com.kunzisoft.keepass.DATABASE_START_TASK_ACTION"
const val DATABASE_STOP_TASK_ACTION = "com.kunzisoft.keepass.DATABASE_STOP_TASK_ACTION" const val DATABASE_STOP_TASK_ACTION = "com.kunzisoft.keepass.DATABASE_STOP_TASK_ACTION"
const val DATABASE_CHECK_TASK_ACTION = "com.kunzisoft.keepass.DATABASE_CHECK_TASK_ACTION"
const val LOCK_ACTION = "com.kunzisoft.keepass.LOCK" const val LOCK_ACTION = "com.kunzisoft.keepass.LOCK"
const val REMOVE_ENTRY_MAGIKEYBOARD_ACTION = "com.kunzisoft.keepass.REMOVE_ENTRY_MAGIKEYBOARD" const val REMOVE_ENTRY_MAGIKEYBOARD_ACTION = "com.kunzisoft.keepass.REMOVE_ENTRY_MAGIKEYBOARD"