From f50881c1fcbb30c5a8fe362eae9a3feb089f4852 Mon Sep 17 00:00:00 2001 From: Andries Smit Date: Sat, 5 Mar 2022 23:33:56 +0100 Subject: [PATCH 1/3] feat: add password timeout --- .../nightscout/androidaps/MainActivity.kt | 1 + app/src/main/res/xml/pref_general.xml | 20 +++++++--- .../utils/protection/ProtectionCheck.kt | 39 +++++++++++++++---- core/src/main/res/values/protection.xml | 2 + 4 files changed, 49 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.kt b/app/src/main/java/info/nightscout/androidaps/MainActivity.kt index dbd152c315..a9c04af798 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.kt @@ -168,6 +168,7 @@ class MainActivity : NoSplashAppCompatActivity() { override fun onResume() { super.onResume() + protectionCheck.resetAuthorization() if (!isProtectionCheckActive) { isProtectionCheckActive = true protectionCheck.queryProtection(this, ProtectionCheck.Protection.APPLICATION, UIRunnable { isProtectionCheckActive = false }, diff --git a/app/src/main/res/xml/pref_general.xml b/app/src/main/res/xml/pref_general.xml index 6b43facf2d..7698187f4a 100644 --- a/app/src/main/res/xml/pref_general.xml +++ b/app/src/main/res/xml/pref_general.xml @@ -1,6 +1,7 @@ + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:validate="http://schemas.android.com/apk/res-auto"> + android:title="@string/patient_name" /> + android:title="@string/master_password" /> + + - \ No newline at end of file + diff --git a/core/src/main/java/info/nightscout/androidaps/utils/protection/ProtectionCheck.kt b/core/src/main/java/info/nightscout/androidaps/utils/protection/ProtectionCheck.kt index 7edc13830e..3441ef8245 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/protection/ProtectionCheck.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/protection/ProtectionCheck.kt @@ -2,16 +2,22 @@ package info.nightscout.androidaps.utils.protection import androidx.fragment.app.FragmentActivity import info.nightscout.androidaps.core.R +import info.nightscout.androidaps.utils.DateUtil import info.nightscout.shared.sharedPreferences.SP +import java.util.concurrent.TimeUnit import javax.inject.Inject import javax.inject.Singleton @Singleton class ProtectionCheck @Inject constructor( val sp: SP, - val passwordCheck: PasswordCheck + val passwordCheck: PasswordCheck, + val dateUtil: DateUtil ) { + private var lastAuthorization = mutableListOf(0L, 0L, 0L) + private val timeout = TimeUnit.SECONDS.toMillis(sp.getInt(R.string.key_protection_timeout, 0).toLong()) + enum class Protection { PREFERENCES, APPLICATION, @@ -61,19 +67,38 @@ class ProtectionCheck @Inject constructor( } } - fun queryProtection(activity: FragmentActivity, protection: Protection, - ok: Runnable?, cancel: Runnable? = null, fail: Runnable? = null) { + fun resetAuthorization() { + lastAuthorization = mutableListOf(0L, 0L, 0L) + } + + private fun activeSession(protection: Protection): Boolean { + val last = lastAuthorization[protection.ordinal] + val diff = dateUtil.now() - last + return diff < timeout + } + + private fun onOk(protection: Protection) { + lastAuthorization[protection.ordinal] = dateUtil.now() + } + + fun queryProtection(activity: FragmentActivity, protection: Protection, ok: Runnable?, cancel: Runnable? = null, fail: Runnable? = null) { + if (activeSession(protection)) { + onOk(protection) + ok?.run() + return + } + when (ProtectionType.values()[sp.getInt(protectionTypeResourceIDs[protection.ordinal], ProtectionType.NONE.ordinal)]) { ProtectionType.NONE -> ok?.run() ProtectionType.BIOMETRIC -> - BiometricCheck.biometricPrompt(activity, titlePassResourceIDs[protection.ordinal], ok, cancel, fail, passwordCheck) + BiometricCheck.biometricPrompt(activity, titlePassResourceIDs[protection.ordinal], { onOk(protection); ok?.run() }, cancel, fail, passwordCheck) ProtectionType.MASTER_PASSWORD -> - passwordCheck.queryPassword(activity, R.string.master_password, R.string.key_master_password, { ok?.run() }, { cancel?.run() }, { fail?.run() }) + passwordCheck.queryPassword(activity, R.string.master_password, R.string.key_master_password, { onOk(protection); ok?.run() }, { cancel?.run() }, { fail?.run() }) ProtectionType.CUSTOM_PASSWORD -> - passwordCheck.queryPassword(activity, titlePassResourceIDs[protection.ordinal], passwordsResourceIDs[protection.ordinal], { ok?.run() }, { cancel?.run() }, { fail?.run() }) + passwordCheck.queryPassword(activity, titlePassResourceIDs[protection.ordinal], passwordsResourceIDs[protection.ordinal], { onOk(protection); ok?.run() }, { cancel?.run() }, { fail?.run() }) ProtectionType.CUSTOM_PIN -> - passwordCheck.queryPassword(activity, titlePinResourceIDs[protection.ordinal], pinsResourceIDs[protection.ordinal], { ok?.run() }, { cancel?.run() }, { fail?.run() }, true) + passwordCheck.queryPassword(activity, titlePinResourceIDs[protection.ordinal], pinsResourceIDs[protection.ordinal], { onOk(protection); ok?.run() }, { cancel?.run() }, { fail?.run() }, true) } } } diff --git a/core/src/main/res/values/protection.xml b/core/src/main/res/values/protection.xml index 807106b726..10e0136fb2 100644 --- a/core/src/main/res/values/protection.xml +++ b/core/src/main/res/values/protection.xml @@ -12,6 +12,7 @@ Application PIN Bolus password Bolus PIN + Time before Bolus and Settings password / PIN expires (seconds) Unlock settings Biometric Custom password @@ -43,4 +44,5 @@ settings_protection application_protection bolus_protection + protection_timeout From 542aba6ea3dc4d353f7193665a990f2815189c28 Mon Sep 17 00:00:00 2001 From: Andries Smit Date: Sun, 6 Mar 2022 21:43:58 +0100 Subject: [PATCH 2/3] feat: add application password retention --- .../java/info/nightscout/androidaps/MainActivity.kt | 1 - .../main/java/info/nightscout/androidaps/MainApp.kt | 4 ++++ .../androidaps/utils/ProcessLifecycleListener.kt | 13 +++++++++++++ app/src/main/res/xml/pref_general.xml | 1 + core/core_dependencies.gradle | 1 + core/src/main/res/values/protection.xml | 3 ++- 6 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/info/nightscout/androidaps/utils/ProcessLifecycleListener.kt diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.kt b/app/src/main/java/info/nightscout/androidaps/MainActivity.kt index a9c04af798..dbd152c315 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.kt @@ -168,7 +168,6 @@ class MainActivity : NoSplashAppCompatActivity() { override fun onResume() { super.onResume() - protectionCheck.resetAuthorization() if (!isProtectionCheckActive) { isProtectionCheckActive = true protectionCheck.queryProtection(this, ProtectionCheck.Protection.APPLICATION, UIRunnable { isProtectionCheckActive = false }, diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.kt b/app/src/main/java/info/nightscout/androidaps/MainApp.kt index 781ab707c3..ef74b5c6f2 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.kt +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.kt @@ -6,6 +6,7 @@ import android.content.IntentFilter import android.net.ConnectivityManager import android.net.wifi.WifiManager import android.os.Build +import androidx.lifecycle.ProcessLifecycleOwner import com.uber.rxdogtag.RxDogTag import dagger.android.AndroidInjector import dagger.android.DaggerApplication @@ -35,6 +36,7 @@ import info.nightscout.androidaps.receivers.TimeDateOrTZChangeReceiver import info.nightscout.androidaps.services.AlarmSoundServiceHelper import info.nightscout.androidaps.utils.ActivityMonitor import info.nightscout.androidaps.utils.DateUtil +import info.nightscout.androidaps.utils.ProcessLifecycleListener import info.nightscout.androidaps.utils.buildHelper.BuildHelper import info.nightscout.androidaps.utils.locale.LocaleHelper import info.nightscout.androidaps.utils.protection.PasswordCheck @@ -70,6 +72,7 @@ class MainApp : DaggerApplication() { @Inject lateinit var passwordCheck: PasswordCheck @Inject lateinit var alarmSoundServiceHelper: AlarmSoundServiceHelper @Inject lateinit var notificationStore: NotificationStore + @Inject lateinit var processLifecycleListener: ProcessLifecycleListener override fun onCreate() { super.onCreate() @@ -77,6 +80,7 @@ class MainApp : DaggerApplication() { RxDogTag.install() setRxErrorHandler() LocaleHelper.update(this) + ProcessLifecycleOwner.get().lifecycle.addObserver(processLifecycleListener) var gitRemote: String? = BuildConfig.REMOTE var commitHash: String? = BuildConfig.HEAD diff --git a/app/src/main/java/info/nightscout/androidaps/utils/ProcessLifecycleListener.kt b/app/src/main/java/info/nightscout/androidaps/utils/ProcessLifecycleListener.kt new file mode 100644 index 0000000000..e1bc3a719b --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/utils/ProcessLifecycleListener.kt @@ -0,0 +1,13 @@ +package info.nightscout.androidaps.utils + +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import info.nightscout.androidaps.utils.protection.ProtectionCheck +import javax.inject.Inject + +class ProcessLifecycleListener @Inject constructor(private val protectionCheck: ProtectionCheck) : DefaultLifecycleObserver { + + override fun onPause(owner: LifecycleOwner) { + protectionCheck.resetAuthorization() + } +} diff --git a/app/src/main/res/xml/pref_general.xml b/app/src/main/res/xml/pref_general.xml index 7698187f4a..3ae0cb84dc 100644 --- a/app/src/main/res/xml/pref_general.xml +++ b/app/src/main/res/xml/pref_general.xml @@ -86,6 +86,7 @@ android:inputType="number" android:key="@string/key_protection_timeout" android:title="@string/protection_timeout_title" + android:summary="@string/protection_timeout_summary" app:defaultValue="0" validate:maxNumber="180" validate:minNumber="0" diff --git a/core/core_dependencies.gradle b/core/core_dependencies.gradle index 7b9748a2d8..a84479cf9f 100644 --- a/core/core_dependencies.gradle +++ b/core/core_dependencies.gradle @@ -14,6 +14,7 @@ dependencies { api "androidx.browser:browser:1.3.0" api "androidx.activity:activity-ktx:${activity_version}" api "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version" + api "androidx.lifecycle:lifecycle-process:$lifecycle_version" api 'androidx.cardview:cardview:1.0.0' api 'androidx.recyclerview:recyclerview:1.2.1' api 'androidx.gridlayout:gridlayout:1.0.0' diff --git a/core/src/main/res/values/protection.xml b/core/src/main/res/values/protection.xml index 10e0136fb2..9f6c0e279b 100644 --- a/core/src/main/res/values/protection.xml +++ b/core/src/main/res/values/protection.xml @@ -12,7 +12,8 @@ Application PIN Bolus password Bolus PIN - Time before Bolus and Settings password / PIN expires (seconds) + Password and PIN retention [s] + Time before the password or PIN should be entered Unlock settings Biometric Custom password From 4a3a264bd7cf607aaa16f1cdff7039ac63988019 Mon Sep 17 00:00:00 2001 From: Andries Smit Date: Mon, 7 Mar 2022 11:49:37 +0100 Subject: [PATCH 3/3] feat: request protection on resume dialog --- .../androidaps/dialogs/CarbsDialog.kt | 17 ++++++++++++++++- .../androidaps/dialogs/ExtendedBolusDialog.kt | 19 ++++++++++++++++++- .../androidaps/dialogs/FillDialog.kt | 16 ++++++++++++++++ .../androidaps/dialogs/InsulinDialog.kt | 17 ++++++++++++++++- .../androidaps/dialogs/LoopDialog.kt | 15 +++++++++++++++ .../androidaps/dialogs/ProfileSwitchDialog.kt | 18 ++++++++++++++++++ .../androidaps/dialogs/TempBasalDialog.kt | 19 ++++++++++++++++++- .../androidaps/dialogs/TempTargetDialog.kt | 18 ++++++++++++++++++ .../androidaps/dialogs/TreatmentDialog.kt | 17 ++++++++++++++++- .../androidaps/dialogs/WizardDialog.kt | 15 +++++++++++++++ app/src/main/res/values/strings.xml | 1 + .../utils/protection/ProtectionCheck.kt | 3 +++ 12 files changed, 170 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt index 60835562dd..6c69d5eae5 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt @@ -27,6 +27,7 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProv import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.alertDialogs.OKDialog +import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.resources.ResourceHelper import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign @@ -50,6 +51,7 @@ class CarbsDialog : DialogFragmentWithDate() { @Inject lateinit var bolusTimer: BolusTimer @Inject lateinit var commandQueue: CommandQueue @Inject lateinit var repository: AppRepository + @Inject lateinit var protectionCheck: ProtectionCheck companion object { @@ -377,4 +379,17 @@ class CarbsDialog : DialogFragmentWithDate() { } return true } -} \ No newline at end of file + + override fun onResume() { + super.onResume() + activity?.let { activity -> + val cancelFail = { + aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.name}") + ToastUtils.showToastInUiThread(ctx, R.string.dialog_cancled) + dismiss() + } + + protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, {}, cancelFail, fail = cancelFail) + } + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt index 7205a36939..7455336aaa 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/ExtendedBolusDialog.kt @@ -22,7 +22,10 @@ import info.nightscout.androidaps.utils.HtmlHelper import info.nightscout.shared.SafeParse import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.extensions.formatColor +import info.nightscout.androidaps.utils.ToastUtils +import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.resources.ResourceHelper +import info.nightscout.shared.logging.LTag import java.text.DecimalFormat import java.util.* import javax.inject.Inject @@ -36,6 +39,7 @@ class ExtendedBolusDialog : DialogFragmentWithDate() { @Inject lateinit var commandQueue: CommandQueue @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var uel: UserEntryLogger + @Inject lateinit var protectionCheck: ProtectionCheck private var _binding: DialogExtendedbolusBinding? = null @@ -106,4 +110,17 @@ class ExtendedBolusDialog : DialogFragmentWithDate() { } return true } -} \ No newline at end of file + + override fun onResume() { + super.onResume() + activity?.let { activity -> + val cancelFail = { + aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.name}") + ToastUtils.showToastInUiThread(ctx, R.string.dialog_cancled) + dismiss() + } + + protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, {}, cancelFail, fail = cancelFail) + } + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt index 54b222ce2c..14158a101a 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/FillDialog.kt @@ -28,6 +28,8 @@ import info.nightscout.androidaps.utils.HtmlHelper import info.nightscout.shared.SafeParse import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.extensions.formatColor +import info.nightscout.androidaps.utils.ToastUtils +import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.resources.ResourceHelper import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign @@ -44,6 +46,7 @@ class FillDialog : DialogFragmentWithDate() { @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var uel: UserEntryLogger @Inject lateinit var repository: AppRepository + @Inject lateinit var protectionCheck: ProtectionCheck private val disposable = CompositeDisposable() @@ -196,4 +199,17 @@ class FillDialog : DialogFragmentWithDate() { } }) } + + override fun onResume() { + super.onResume() + activity?.let { activity -> + val cancelFail = { + aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.name}") + ToastUtils.showToastInUiThread(ctx, R.string.dialog_cancled) + dismiss() + } + + protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, {}, cancelFail, fail = cancelFail) + } + } } diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt index 21eb81ebce..46924a1fdc 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt @@ -28,6 +28,7 @@ import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.extensions.toSignedString +import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.shared.SafeParse import io.reactivex.rxjava3.disposables.CompositeDisposable @@ -52,6 +53,7 @@ class InsulinDialog : DialogFragmentWithDate() { @Inject lateinit var config: Config @Inject lateinit var bolusTimer: BolusTimer @Inject lateinit var uel: UserEntryLogger + @Inject lateinit var protectionCheck: ProtectionCheck companion object { @@ -255,4 +257,17 @@ class InsulinDialog : DialogFragmentWithDate() { } return true } -} \ No newline at end of file + + override fun onResume() { + super.onResume() + activity?.let { activity -> + val cancelFail = { + aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.name}") + ToastUtils.showToastInUiThread(ctx, R.string.dialog_cancled) + dismiss() + } + + protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, {}, cancelFail, fail = cancelFail) + } + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/LoopDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/LoopDialog.kt index 8e67a0ed6e..109a433afa 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/LoopDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/LoopDialog.kt @@ -38,6 +38,7 @@ import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.androidaps.utils.alertDialogs.OKDialog +import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.shared.sharedPreferences.SP import io.reactivex.rxjava3.disposables.CompositeDisposable @@ -62,6 +63,7 @@ class LoopDialog : DaggerDialogFragment() { @Inject lateinit var dateUtil: DateUtil @Inject lateinit var repository: AppRepository @Inject lateinit var objectivePlugin: ObjectivesPlugin + @Inject lateinit var protectionCheck: ProtectionCheck private var showOkCancel: Boolean = true private var _binding: DialogLoopBinding? = null @@ -437,4 +439,17 @@ class LoopDialog : DaggerDialogFragment() { aapsLogger.debug(e.localizedMessage ?: e.toString()) } } + + override fun onResume() { + super.onResume() + activity?.let { activity -> + val cancelFail = { + aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.name}") + ToastUtils.showToastInUiThread(ctx, R.string.dialog_cancled) + dismiss() + } + + protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, {}, cancelFail, fail = cancelFail) + } + } } diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/ProfileSwitchDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/ProfileSwitchDialog.kt index 70ed31b8bc..04c6167f12 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/ProfileSwitchDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/ProfileSwitchDialog.kt @@ -1,5 +1,6 @@ package info.nightscout.androidaps.dialogs +import android.content.Context import android.os.Bundle import android.text.Editable import android.text.TextWatcher @@ -30,7 +31,9 @@ import info.nightscout.androidaps.utils.DefaultValueHelper import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.HtmlHelper import info.nightscout.androidaps.utils.T +import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.androidaps.utils.alertDialogs.OKDialog +import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.resources.ResourceHelper import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign @@ -51,6 +54,8 @@ class ProfileSwitchDialog : DialogFragmentWithDate() { @Inject lateinit var hardLimits: HardLimits @Inject lateinit var rxBus: RxBus @Inject lateinit var defaultValueHelper: DefaultValueHelper + @Inject lateinit var ctx: Context + @Inject lateinit var protectionCheck: ProtectionCheck private var profileIndex: Int? = null @@ -245,4 +250,17 @@ class ProfileSwitchDialog : DialogFragmentWithDate() { } return true } + + override fun onResume() { + super.onResume() + activity?.let { activity -> + val cancelFail = { + aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.name}") + ToastUtils.showToastInUiThread(ctx, R.string.dialog_cancled) + dismiss() + } + + protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, {}, cancelFail, fail = cancelFail) + } + } } diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt index d458055b9d..c634c92f2f 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/TempBasalDialog.kt @@ -20,7 +20,10 @@ import info.nightscout.androidaps.utils.HtmlHelper import info.nightscout.shared.SafeParse import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.extensions.formatColor +import info.nightscout.androidaps.utils.ToastUtils +import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.resources.ResourceHelper +import info.nightscout.shared.logging.LTag import java.text.DecimalFormat import java.util.* import javax.inject.Inject @@ -35,6 +38,7 @@ class TempBasalDialog : DialogFragmentWithDate() { @Inject lateinit var commandQueue: CommandQueue @Inject lateinit var ctx: Context @Inject lateinit var uel: UserEntryLogger + @Inject lateinit var protectionCheck: ProtectionCheck private var isPercentPump = true @@ -141,4 +145,17 @@ class TempBasalDialog : DialogFragmentWithDate() { } return true } -} \ No newline at end of file + + override fun onResume() { + super.onResume() + activity?.let { activity -> + val cancelFail = { + aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.name}") + ToastUtils.showToastInUiThread(ctx, R.string.dialog_cancled) + dismiss() + } + + protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, {}, cancelFail, fail = cancelFail) + } + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/TempTargetDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/TempTargetDialog.kt index 16d41ef689..c282bffd1c 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/TempTargetDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/TempTargetDialog.kt @@ -1,5 +1,6 @@ package info.nightscout.androidaps.dialogs +import android.content.Context import android.os.Bundle import android.view.LayoutInflater import android.view.View @@ -26,7 +27,9 @@ import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.utils.DefaultValueHelper import info.nightscout.androidaps.utils.HtmlHelper +import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.androidaps.utils.alertDialogs.OKDialog +import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.resources.ResourceHelper import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign @@ -43,6 +46,8 @@ class TempTargetDialog : DialogFragmentWithDate() { @Inject lateinit var defaultValueHelper: DefaultValueHelper @Inject lateinit var uel: UserEntryLogger @Inject lateinit var repository: AppRepository + @Inject lateinit var ctx: Context + @Inject lateinit var protectionCheck: ProtectionCheck private lateinit var reasonList: List @@ -218,4 +223,17 @@ class TempTargetDialog : DialogFragmentWithDate() { } return true } + + override fun onResume() { + super.onResume() + activity?.let { activity -> + val cancelFail = { + aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.name}") + ToastUtils.showToastInUiThread(ctx, R.string.dialog_cancled) + dismiss() + } + + protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, {}, cancelFail, fail = cancelFail) + } + } } diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt index 0e8a509517..bf82dcb38a 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/TreatmentDialog.kt @@ -30,6 +30,7 @@ import info.nightscout.shared.SafeParse import info.nightscout.androidaps.utils.ToastUtils import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.extensions.formatColor +import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.resources.ResourceHelper import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign @@ -48,6 +49,7 @@ class TreatmentDialog : DialogFragmentWithDate() { @Inject lateinit var config: Config @Inject lateinit var uel: UserEntryLogger @Inject lateinit var repository: AppRepository + @Inject lateinit var protectionCheck: ProtectionCheck private val disposable = CompositeDisposable() @@ -201,4 +203,17 @@ class TreatmentDialog : DialogFragmentWithDate() { } return true } -} \ No newline at end of file + + override fun onResume() { + super.onResume() + activity?.let { activity -> + val cancelFail = { + aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.name}") + ToastUtils.showToastInUiThread(ctx, R.string.dialog_cancled) + dismiss() + } + + protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, {}, cancelFail, fail = cancelFail) + } + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt index 36c8c90a1a..852dbab3f2 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt @@ -29,6 +29,7 @@ import info.nightscout.androidaps.extensions.toVisibility import info.nightscout.androidaps.extensions.valueToUnits import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.utils.* +import info.nightscout.androidaps.utils.protection.ProtectionCheck import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.shared.sharedPreferences.SP @@ -55,6 +56,7 @@ class WizardDialog : DaggerDialogFragment() { @Inject lateinit var iobCobCalculator: IobCobCalculator @Inject lateinit var repository: AppRepository @Inject lateinit var dateUtil: DateUtil + @Inject lateinit var protectionCheck: ProtectionCheck private var wizard: BolusWizard? = null private var calculatedPercentage = 100.0 @@ -497,4 +499,17 @@ class WizardDialog : DaggerDialogFragment() { aapsLogger.debug(e.localizedMessage ?: "") } } + + override fun onResume() { + super.onResume() + activity?.let { activity -> + val cancelFail = { + aapsLogger.debug(LTag.APS, "Dialog canceled on resume protection: ${this.javaClass.name}") + ToastUtils.showToastInUiThread(ctx, R.string.dialog_cancled) + dismiss() + } + + protectionCheck.queryProtection(activity, ProtectionCheck.Protection.BOLUS, {}, cancelFail, fail = cancelFail) + } + } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d35da6ce93..5673070d38 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1224,4 +1224,5 @@ Show loop %1$d selected Sort + Dialog canceled diff --git a/core/src/main/java/info/nightscout/androidaps/utils/protection/ProtectionCheck.kt b/core/src/main/java/info/nightscout/androidaps/utils/protection/ProtectionCheck.kt index 3441ef8245..28661c0fd0 100644 --- a/core/src/main/java/info/nightscout/androidaps/utils/protection/ProtectionCheck.kt +++ b/core/src/main/java/info/nightscout/androidaps/utils/protection/ProtectionCheck.kt @@ -58,6 +58,9 @@ class ProtectionCheck @Inject constructor( R.string.bolus_pin) fun isLocked(protection: Protection): Boolean { + if (activeSession(protection)) { + return false + } return when (ProtectionType.values()[sp.getInt(protectionTypeResourceIDs[protection.ordinal], ProtectionType.NONE.ordinal)]) { ProtectionType.NONE -> false ProtectionType.BIOMETRIC -> true