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
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.*
import android.content.Context.BIND_ABOVE_CLIENT
import android.content.Context.BIND_NOT_FOREGROUND
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.*
import androidx.fragment.app.FragmentActivity
import com.kunzisoft.keepass.R
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_GROUP_TASK
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_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.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.tasks.ActionRunnable
import com.kunzisoft.keepass.tasks.ProgressTaskDialogFragment
import com.kunzisoft.keepass.tasks.ProgressTaskDialogFragment.Companion.UNDEFINED
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_STOP_TASK_ACTION
import java.io.File
import java.util.*
import kotlin.collections.ArrayList
class ProgressDialogThread(private val activity: FragmentActivity,
var onActionFinish: (actionTask: String,
result: ActionRunnable.Result) -> Unit) {
private var progressTaskDialogFragment: ProgressTaskDialogFragment? = null
private var databaseTaskBroadcastReceiver: BroadcastReceiver? = null
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()
// Show the dialog
progressTaskDialogFragment = ProgressTaskDialogFragment.build(
intent.getIntExtra(DATABASE_TASK_TITLE_KEY, R.string.loading_database),
intent.getIntExtra(DATABASE_TASK_SUBTITLE_KEY, ProgressTaskDialogFragment.UNDEFINED),
intent.getIntExtra(DATABASE_TASK_MESSAGE_KEY, ProgressTaskDialogFragment.UNDEFINED))
val title = intent?.getIntExtra(DATABASE_TASK_TITLE_KEY, R.string.loading_database) ?: UNDEFINED
val subTitle = intent?.getIntExtra(DATABASE_TASK_WARNING_KEY, UNDEFINED) ?: UNDEFINED
val message = intent?.getIntExtra(DATABASE_TASK_MESSAGE_KEY, UNDEFINED) ?: UNDEFINED
progressTaskDialogFragment = ProgressTaskDialogFragment.build(title, subTitle, message)
ProgressTaskDialogFragment.start(activity, progressTaskDialogFragment!!)
}
@@ -62,7 +124,6 @@ class ProgressDialogThread(private val activity: FragmentActivity,
// Remove the progress task
ProgressTaskDialogFragment.stop(activity)
TimeoutHelper.releaseTemporarilyDisableTimeoutAndLockIfTimeout(activity)
activity.stopService(intentDatabaseTask)
if (intent != null
&& intent.hasExtra(ACTION_TASK_KEY)
&& intent.hasExtra(RESULT_KEY))
@@ -97,10 +158,12 @@ class ProgressDialogThread(private val activity: FragmentActivity,
)
// 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() {
activity.unbindService(serviceConnection)
activity.unregisterReceiver(databaseTaskBroadcastReceiver)
}

View File

@@ -1,12 +1,8 @@
package com.kunzisoft.keepass.notifications
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.net.Uri
import android.os.AsyncTask
import android.os.Bundle
import android.os.*
import android.util.Log
import com.kunzisoft.keepass.R
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.tasks.ActionRunnable
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_STOP_TASK_ACTION
import java.io.File
import java.util.*
import kotlin.collections.ArrayList
import android.os.Bundle
class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdater {
@@ -31,27 +27,44 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
private var actionRunnableAsyncTask: ActionRunnableAsyncTask? = null
private var checkBroadcastReceiver: BroadcastReceiver? = null
private var actionStatusHandler = ActionStatusHandler()
private var actionMessenger = Messenger(actionStatusHandler)
override fun onCreate() {
super.onCreate()
private class ActionStatusHandler: Handler() {
var titleId: Int? = null
var messageId: Int? = null
var warningId: Int? = null
checkBroadcastReceiver = object: BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
sendBroadcast(Intent(DATABASE_START_TASK_ACTION))
override fun handleMessage(message: Message?) {
when (message?.what) {
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() {
unregisterReceiver(checkBroadcastReceiver)
super.onDestroy()
override fun onBind(intent: Intent): IBinder? {
return actionMessenger.binder
}
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
else -> R.string.loading_database
}
val subtitleId: Int? = when (intent.action) {
else -> null
}
val messageId: Int? = when (intent.action) {
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) {
ACTION_DATABASE_CREATE_TASK -> buildDatabaseCreateActionTask(intent)
@@ -107,13 +122,16 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
ACTION_DATABASE_COPY_NODES_TASK,
ACTION_DATABASE_MOVE_NODES_TASK,
ACTION_DATABASE_DELETE_NODES_TASK -> {
actionStatusHandler.titleId = titleId
actionStatusHandler.messageId = messageId
actionStatusHandler.warningId = warningId
newNotification(intent.getIntExtra(DATABASE_TASK_TITLE_KEY, titleId))
actionRunnableAsyncTask = ActionRunnableAsyncTask(this,
{
sendBroadcast(Intent(DATABASE_START_TASK_ACTION).apply {
putExtra(DATABASE_TASK_TITLE_KEY, titleId)
putExtra(DATABASE_TASK_SUBTITLE_KEY, subtitleId)
putExtra(DATABASE_TASK_MESSAGE_KEY, messageId)
putExtra(DATABASE_TASK_WARNING_KEY, warningId)
})
}, { result ->
@@ -121,6 +139,7 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
putExtra(ACTION_TASK_KEY, intent.action)
putExtra(RESULT_KEY, result.toBundle())
})
stopSelf()
}
)
actionRunnable?.let { actionRunnableNotNull ->
@@ -412,9 +431,13 @@ class DatabaseTaskNotificationService : NotificationService(), ProgressTaskUpdat
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_SUBTITLE_KEY = "DATABASE_TASK_SUBTITLE_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_SAVE_TASK = "ACTION_DATABASE_SAVE_TASK"

View File

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