CommandQueueImpl -> implementation module

This commit is contained in:
Milos Kozak 2022-11-01 11:39:40 +01:00
parent 369bf25647
commit 4c5d015b40
54 changed files with 832 additions and 356 deletions

View file

@ -44,9 +44,7 @@ import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.constraints.signatureVerifier.SignatureVerifierPlugin import info.nightscout.androidaps.plugins.constraints.signatureVerifier.SignatureVerifierPlugin
import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtils import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtils
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.setupwizard.SetupWizardActivity import info.nightscout.androidaps.setupwizard.SetupWizardActivity
import info.nightscout.androidaps.utils.AndroidPermission
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.extensions.isRunningRealPumpTest import info.nightscout.androidaps.utils.extensions.isRunningRealPumpTest
@ -72,7 +70,7 @@ class MainActivity : NoSplashAppCompatActivity() {
@Inject lateinit var androidPermission: AndroidPermission @Inject lateinit var androidPermission: AndroidPermission
@Inject lateinit var sp: SP @Inject lateinit var sp: SP
@Inject lateinit var versionCheckerUtils: VersionCheckerUtils @Inject lateinit var versionCheckerUtils: VersionCheckerUtils
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin @Inject lateinit var smsCommunicator: SmsCommunicator
@Inject lateinit var loop: Loop @Inject lateinit var loop: Loop
@Inject lateinit var nsSettingsStatus: NSSettingsStatus @Inject lateinit var nsSettingsStatus: NSSettingsStatus
@Inject lateinit var buildHelper: BuildHelper @Inject lateinit var buildHelper: BuildHelper
@ -152,7 +150,7 @@ class MainActivity : NoSplashAppCompatActivity() {
androidPermission.notifyForBatteryOptimizationPermission(this) androidPermission.notifyForBatteryOptimizationPermission(this)
if (!config.NSCLIENT) androidPermission.notifyForLocationPermissions(this) if (!config.NSCLIENT) androidPermission.notifyForLocationPermissions(this)
if (config.PUMPDRIVERS) { if (config.PUMPDRIVERS) {
androidPermission.notifyForSMSPermissions(this, smsCommunicatorPlugin) androidPermission.notifyForSMSPermissions(this, smsCommunicator)
androidPermission.notifyForSystemWindowPermissions(this) androidPermission.notifyForSystemWindowPermissions(this)
androidPermission.notifyForBtConnectPermission(this) androidPermission.notifyForBtConnectPermission(this)
} }

View file

@ -23,8 +23,10 @@ import info.nightscout.androidaps.database.transactions.VersionChangeTransaction
import info.nightscout.androidaps.db.CompatDBHelper import info.nightscout.androidaps.db.CompatDBHelper
import info.nightscout.androidaps.di.DaggerAppComponent import info.nightscout.androidaps.di.DaggerAppComponent
import info.nightscout.androidaps.di.StaticInjector import info.nightscout.androidaps.di.StaticInjector
import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.ConfigBuilder import info.nightscout.androidaps.interfaces.ConfigBuilder
import info.nightscout.androidaps.interfaces.LocalAlertUtils
import info.nightscout.androidaps.interfaces.PluginBase import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.logging.UserEntryLogger
@ -41,9 +43,7 @@ import info.nightscout.androidaps.receivers.TimeDateOrTZChangeReceiver
import info.nightscout.androidaps.services.AlarmSoundServiceHelper import info.nightscout.androidaps.services.AlarmSoundServiceHelper
import info.nightscout.androidaps.utils.ActivityMonitor import info.nightscout.androidaps.utils.ActivityMonitor
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.LocalAlertUtils
import info.nightscout.androidaps.utils.ProcessLifecycleListener import info.nightscout.androidaps.utils.ProcessLifecycleListener
import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.utils.locale.LocaleHelper import info.nightscout.androidaps.utils.locale.LocaleHelper
import info.nightscout.androidaps.widget.updateWidget import info.nightscout.androidaps.widget.updateWidget
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger

View file

@ -22,6 +22,7 @@ import info.nightscout.androidaps.plugins.pump.common.di.RileyLinkModule
import info.nightscout.androidaps.plugins.pump.medtronic.di.MedtronicModule import info.nightscout.androidaps.plugins.pump.medtronic.di.MedtronicModule
import info.nightscout.androidaps.plugins.pump.omnipod.dash.di.OmnipodDashModule import info.nightscout.androidaps.plugins.pump.omnipod.dash.di.OmnipodDashModule
import info.nightscout.androidaps.plugins.pump.omnipod.eros.di.OmnipodErosModule import info.nightscout.androidaps.plugins.pump.omnipod.eros.di.OmnipodErosModule
import info.nightscout.implementation.di.CommandQueueModule
import info.nightscout.shared.di.SharedModule import info.nightscout.shared.di.SharedModule
import info.nightscout.ui.di.UiModule import info.nightscout.ui.di.UiModule
import javax.inject.Singleton import javax.inject.Singleton

View file

@ -8,8 +8,28 @@ import dagger.Provides
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.androidaps.interfaces.AndroidPermission
import info.nightscout.androidaps.interfaces.Autotune
import info.nightscout.androidaps.interfaces.BolusTimer
import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.interfaces.CarbTimer
import info.nightscout.androidaps.interfaces.CommandQueue
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.ConfigBuilder
import info.nightscout.androidaps.interfaces.DataSyncSelector
import info.nightscout.androidaps.interfaces.IconsProvider
import info.nightscout.androidaps.interfaces.ImportExportPrefs
import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.LocalAlertUtils
import info.nightscout.androidaps.interfaces.Loop
import info.nightscout.androidaps.interfaces.NotificationHolder
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.interfaces.SmsCommunicator
import info.nightscout.androidaps.interfaces.XDripBroadcast
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
@ -23,23 +43,24 @@ import info.nightscout.androidaps.plugins.general.nsclient.data.DeviceStatusData
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.plugins.pump.PumpSyncImplementation import info.nightscout.androidaps.plugins.pump.PumpSyncImplementation
import info.nightscout.androidaps.queue.CommandQueueImplementation
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.androidNotification.NotificationHolderImpl import info.nightscout.androidaps.utils.androidNotification.NotificationHolderImpl
import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl
import info.nightscout.androidaps.utils.buildHelper.ConfigImpl import info.nightscout.androidaps.utils.buildHelper.ConfigImpl
import info.nightscout.androidaps.utils.resources.IconsProviderImplementation import info.nightscout.androidaps.utils.resources.IconsProviderImplementation
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.implementation.XDripBroadcastImpl
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.rx.DefaultAapsSchedulers import info.nightscout.androidaps.utils.rx.DefaultAapsSchedulers
import info.nightscout.androidaps.utils.storage.FileStorage import info.nightscout.androidaps.utils.storage.FileStorage
import info.nightscout.androidaps.utils.storage.Storage import info.nightscout.androidaps.utils.storage.Storage
import info.nightscout.implementation.AndroidPermissionImpl
import info.nightscout.implementation.BolusTimerImpl import info.nightscout.implementation.BolusTimerImpl
import info.nightscout.implementation.CarbTimerImpl import info.nightscout.implementation.CarbTimerImpl
import info.nightscout.implementation.LocalAlertUtilsImpl
import info.nightscout.implementation.XDripBroadcastImpl
import info.nightscout.implementation.queue.CommandQueueImplementation
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import javax.inject.Singleton import javax.inject.Singleton
@ -109,10 +130,12 @@ open class AppModule {
@Binds fun bindSmsCommunicatorInterface(smsCommunicatorPlugin: SmsCommunicatorPlugin): SmsCommunicator @Binds fun bindSmsCommunicatorInterface(smsCommunicatorPlugin: SmsCommunicatorPlugin): SmsCommunicator
@Binds fun bindDataSyncSelector(dataSyncSelectorImplementation: DataSyncSelectorImplementation): DataSyncSelector @Binds fun bindDataSyncSelector(dataSyncSelectorImplementation: DataSyncSelectorImplementation): DataSyncSelector
@Binds fun bindPumpSync(pumpSyncImplementation: PumpSyncImplementation): PumpSync @Binds fun bindPumpSyncInterface(pumpSyncImplementation: PumpSyncImplementation): PumpSync
@Binds fun bindXDripBroadcast(xDripBroadcastImpl: XDripBroadcastImpl): XDripBroadcast @Binds fun bindXDripBroadcastInterface(xDripBroadcastImpl: XDripBroadcastImpl): XDripBroadcast
@Binds fun bindCarbTimer(carbTimer: CarbTimerImpl): CarbTimer @Binds fun bindCarbTimerInterface(carbTimer: CarbTimerImpl): CarbTimer
@Binds fun bindBolusTimer(bolusTimer: BolusTimerImpl): BolusTimer @Binds fun bindBolusTimerInterface(bolusTimer: BolusTimerImpl): BolusTimer
@Binds fun bindAndroidPermissionInterface(androidPermission: AndroidPermissionImpl): AndroidPermission
@Binds fun bindLocalAlertUtilsInterface(localAlertUtils: LocalAlertUtilsImpl): LocalAlertUtils
} }
} }

View file

@ -9,6 +9,5 @@ import info.nightscout.androidaps.plugins.general.overview.notifications.Notific
@Suppress("unused") @Suppress("unused")
abstract class OverviewModule { abstract class OverviewModule {
@ContributesAndroidInjector abstract fun notificationWithActionInjector(): NotificationWithAction @ContributesAndroidInjector abstract fun notificationWithActionInjector(): NotificationWithAction
@ContributesAndroidInjector abstract fun graphDataInjector(): GraphData @ContributesAndroidInjector abstract fun graphDataInjector(): GraphData
} }

View file

@ -13,7 +13,12 @@ import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.work.* import androidx.work.ExistingWorkPolicy
import androidx.work.OneTimeWorkRequest
import androidx.work.WorkManager
import androidx.work.Worker
import androidx.work.WorkerParameters
import androidx.work.workDataOf
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.BuildConfig import info.nightscout.androidaps.BuildConfig
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
@ -25,13 +30,21 @@ import info.nightscout.androidaps.database.entities.UserEntry.Action
import info.nightscout.androidaps.database.entities.UserEntry.Sources import info.nightscout.androidaps.database.entities.UserEntry.Sources
import info.nightscout.androidaps.diaconn.events.EventDiaconnG8PumpLogReset import info.nightscout.androidaps.diaconn.events.EventDiaconnG8PumpLogReset
import info.nightscout.androidaps.events.EventAppExit import info.nightscout.androidaps.events.EventAppExit
import info.nightscout.androidaps.interfaces.AndroidPermission
import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.ImportExportPrefs import info.nightscout.androidaps.interfaces.ImportExportPrefs
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.maintenance.formats.* import info.nightscout.androidaps.plugins.general.maintenance.formats.EncryptedPrefsFormat
import info.nightscout.androidaps.utils.AndroidPermission import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefFileNotFoundError
import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefIOError
import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefMetadata
import info.nightscout.androidaps.plugins.general.maintenance.formats.Prefs
import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefsFormat
import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefsMetadataKey
import info.nightscout.androidaps.plugins.general.maintenance.formats.PrefsStatus
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.MidnightTime import info.nightscout.androidaps.utils.MidnightTime
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
@ -40,7 +53,6 @@ import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.alertDialogs.PrefImportSummaryDialog import info.nightscout.androidaps.utils.alertDialogs.PrefImportSummaryDialog
import info.nightscout.androidaps.utils.alertDialogs.TwoMessagesAlertDialog import info.nightscout.androidaps.utils.alertDialogs.TwoMessagesAlertDialog
import info.nightscout.androidaps.utils.alertDialogs.WarningDialog import info.nightscout.androidaps.utils.alertDialogs.WarningDialog
import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.utils.protection.PasswordCheck import info.nightscout.androidaps.utils.protection.PasswordCheck
import info.nightscout.androidaps.utils.storage.Storage import info.nightscout.androidaps.utils.storage.Storage
import info.nightscout.androidaps.utils.userEntry.UserEntryPresentationHelper import info.nightscout.androidaps.utils.userEntry.UserEntryPresentationHelper
@ -251,13 +263,13 @@ class ImportExportPrefsImpl @Inject constructor(
activity, rh.gs(R.string.preferences_export_canceled) activity, rh.gs(R.string.preferences_export_canceled)
+ "\n\n" + rh.gs(R.string.filenotfound) + "\n\n" + rh.gs(R.string.filenotfound)
+ ": " + e.message + ": " + e.message
+ "\n\n" + rh.gs(R.string.needstoragepermission) + "\n\n" + rh.gs(R.string.need_storage_permission)
) )
log.error(LTag.CORE, "File system exception", e) log.error(LTag.CORE, "File system exception", e)
} catch (e: PrefIOError) { } catch (e: PrefIOError) {
ToastUtils.Long.errorToast( ToastUtils.Long.errorToast(
activity, rh.gs(R.string.preferences_export_canceled) activity, rh.gs(R.string.preferences_export_canceled)
+ "\n\n" + rh.gs(R.string.needstoragepermission) + "\n\n" + rh.gs(R.string.need_storage_permission)
+ ": " + e.message + ": " + e.message
) )
log.error(LTag.CORE, "File system exception", e) log.error(LTag.CORE, "File system exception", e)

View file

@ -1,12 +1,23 @@
package info.nightscout.androidaps.plugins.general.overview package info.nightscout.androidaps.plugins.general.overview
import androidx.annotation.StringRes
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference import androidx.preference.SwitchPreference
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.events.EventPumpStatusChanged import info.nightscout.androidaps.events.EventPumpStatusChanged
import info.nightscout.androidaps.extensions.* import info.nightscout.androidaps.extensions.putDouble
import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.extensions.putInt
import info.nightscout.androidaps.extensions.putString
import info.nightscout.androidaps.extensions.storeDouble
import info.nightscout.androidaps.extensions.storeInt
import info.nightscout.androidaps.extensions.storeString
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.Overview
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginDescription
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
@ -15,6 +26,7 @@ import info.nightscout.androidaps.plugins.general.overview.events.EventUpdateOve
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.Scale import info.nightscout.androidaps.plugins.general.overview.graphExtensions.Scale
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.ScaledDataPoint import info.nightscout.androidaps.plugins.general.overview.graphExtensions.ScaledDataPoint
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationStore import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationStore
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
@ -56,6 +68,18 @@ class OverviewPlugin @Inject constructor(
private var disposable: CompositeDisposable = CompositeDisposable() private var disposable: CompositeDisposable = CompositeDisposable()
override val overviewBus = RxBus(aapsSchedulers, aapsLogger) override val overviewBus = RxBus(aapsSchedulers, aapsLogger)
override fun addNotification(id: Int, text: String, level: Int, @StringRes actionButtonId: Int, action: Runnable) {
rxBus.send(
EventNewNotification(
NotificationWithAction(injector, id, text, level).apply {
action(actionButtonId, action)
})
)
}
override fun dismissNotification(id: Int) {
rxBus.send(EventDismissNotification(id))
}
class DeviationDataPoint(x: Double, y: Double, var color: Int, scale: Scale) : ScaledDataPoint(x, y, scale) class DeviationDataPoint(x: Double, y: Double, var color: Int, scale: Scale) : ScaledDataPoint(x, y, scale)

View file

@ -4,14 +4,16 @@ import android.os.SystemClock
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.Sms
import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.CommandQueue
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.interfaces.SmsCommunicator
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag
import javax.inject.Inject import javax.inject.Inject
class AuthRequest internal constructor( class AuthRequest internal constructor(
@ -22,7 +24,7 @@ class AuthRequest internal constructor(
val action: SmsAction) { val action: SmsAction) {
@Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin @Inject lateinit var smsCommunicator: SmsCommunicator
@Inject lateinit var rh: ResourceHelper @Inject lateinit var rh: ResourceHelper
@Inject lateinit var otp: OneTimePassword @Inject lateinit var otp: OneTimePassword
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
@ -34,7 +36,7 @@ class AuthRequest internal constructor(
init { init {
injector.androidInjector().inject(this) injector.androidInjector().inject(this)
date = dateUtil.now() date = dateUtil.now()
smsCommunicatorPlugin.sendSMS(Sms(requester.phoneNumber, requestText)) smsCommunicator.sendSMS(Sms(requester.phoneNumber, requestText))
} }
private fun codeIsValid(toValidate: String): Boolean = private fun codeIsValid(toValidate: String): Boolean =
@ -48,7 +50,7 @@ class AuthRequest internal constructor(
if (!codeIsValid(codeReceived)) { if (!codeIsValid(codeReceived)) {
processed = true processed = true
aapsLogger.debug(LTag.SMS, "Wrong code") aapsLogger.debug(LTag.SMS, "Wrong code")
smsCommunicatorPlugin.sendSMS(Sms(requester.phoneNumber, rh.gs(R.string.sms_wrongcode))) smsCommunicator.sendSMS(Sms(requester.phoneNumber, rh.gs(R.string.sms_wrongcode)))
return return
} }
if (dateUtil.now() - date < Constants.SMS_CONFIRM_TIMEOUT) { if (dateUtil.now() - date < Constants.SMS_CONFIRM_TIMEOUT) {
@ -62,7 +64,7 @@ class AuthRequest internal constructor(
} }
if (commandQueue.size() != 0) { if (commandQueue.size() != 0) {
aapsLogger.debug(LTag.SMS, "Command timed out: " + requester.text) aapsLogger.debug(LTag.SMS, "Command timed out: " + requester.text)
smsCommunicatorPlugin.sendSMS(Sms(requester.phoneNumber, rh.gs(R.string.sms_timeout_while_wating))) smsCommunicator.sendSMS(Sms(requester.phoneNumber, rh.gs(R.string.sms_timeout_while_wating)))
return return
} }
} }

View file

@ -5,6 +5,7 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import dagger.android.support.DaggerFragment import dagger.android.support.DaggerFragment
import info.nightscout.androidaps.data.Sms
import info.nightscout.androidaps.databinding.SmscommunicatorFragmentBinding import info.nightscout.androidaps.databinding.SmscommunicatorFragmentBinding
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.smsCommunicator.events.EventSmsCommunicatorUpdateGui import info.nightscout.androidaps.plugins.general.smsCommunicator.events.EventSmsCommunicatorUpdateGui

View file

@ -15,6 +15,7 @@ import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.annotations.OpenForTesting import info.nightscout.androidaps.annotations.OpenForTesting
import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.Sms
import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.OfflineEvent import info.nightscout.androidaps.database.entities.OfflineEvent
import info.nightscout.androidaps.database.entities.TemporaryTarget import info.nightscout.androidaps.database.entities.TemporaryTarget
@ -184,7 +185,6 @@ class SmsCommunicatorPlugin @Inject constructor(
(context.applicationContext as HasAndroidInjector).androidInjector().inject(this) (context.applicationContext as HasAndroidInjector).androidInjector().inject(this)
} }
@Suppress("SpellCheckingInspection")
override fun doWork(): Result { override fun doWork(): Result {
val bundle = dataWorkerStorage.pickupBundle(inputData.getLong(DataWorkerStorage.STORE_KEY, -1)) val bundle = dataWorkerStorage.pickupBundle(inputData.getLong(DataWorkerStorage.STORE_KEY, -1))
?: return Result.failure(workDataOf("Error" to "missing input data")) ?: return Result.failure(workDataOf("Error" to "missing input data"))
@ -1099,7 +1099,7 @@ class SmsCommunicatorPlugin @Inject constructor(
} }
} }
fun sendSMS(sms: Sms): Boolean { override fun sendSMS(sms: Sms): Boolean {
sms.text = stripAccents(sms.text) sms.text = stripAccents(sms.text)
try { try {
aapsLogger.debug(LTag.SMS, "Sending SMS to " + sms.phoneNumber + ": " + sms.text) aapsLogger.debug(LTag.SMS, "Sending SMS to " + sms.phoneNumber + ": " + sms.text)

View file

@ -22,6 +22,7 @@ import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.CommandQueue
import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.IobCobCalculator import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.LocalAlertUtils
import info.nightscout.androidaps.interfaces.Loop import info.nightscout.androidaps.interfaces.Loop
import info.nightscout.androidaps.interfaces.PluginBase import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ProfileFunction
@ -32,7 +33,6 @@ import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin
import info.nightscout.androidaps.queue.commands.Command import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.LocalAlertUtils
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.widget.updateWidget import info.nightscout.androidaps.widget.updateWidget
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger

View file

@ -12,7 +12,15 @@ import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.ProfileSealed import info.nightscout.androidaps.data.ProfileSealed
import info.nightscout.androidaps.dialogs.ProfileSwitchDialog import info.nightscout.androidaps.dialogs.ProfileSwitchDialog
import info.nightscout.androidaps.events.EventPumpStatusChanged import info.nightscout.androidaps.events.EventPumpStatusChanged
import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.AndroidPermission
import info.nightscout.androidaps.interfaces.CommandQueue
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.ConfigBuilder
import info.nightscout.androidaps.interfaces.ImportExportPrefs
import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesFragment import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesFragment
@ -24,15 +32,25 @@ import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin
import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange
import info.nightscout.androidaps.plugins.pump.omnipod.dash.OmnipodDashPumpPlugin import info.nightscout.androidaps.plugins.pump.omnipod.dash.OmnipodDashPumpPlugin
import info.nightscout.androidaps.plugins.pump.omnipod.eros.OmnipodErosPumpPlugin import info.nightscout.androidaps.plugins.pump.omnipod.eros.OmnipodErosPumpPlugin
import info.nightscout.androidaps.setupwizard.elements.* import info.nightscout.androidaps.setupwizard.elements.SWBreak
import info.nightscout.androidaps.setupwizard.elements.SWButton
import info.nightscout.androidaps.setupwizard.elements.SWEditEncryptedPassword
import info.nightscout.androidaps.setupwizard.elements.SWEditIntNumber
import info.nightscout.androidaps.setupwizard.elements.SWEditNumber
import info.nightscout.androidaps.setupwizard.elements.SWEditNumberWithUnits
import info.nightscout.androidaps.setupwizard.elements.SWEditString
import info.nightscout.androidaps.setupwizard.elements.SWEditUrl
import info.nightscout.androidaps.setupwizard.elements.SWFragment
import info.nightscout.androidaps.setupwizard.elements.SWHtmlLink
import info.nightscout.androidaps.setupwizard.elements.SWInfoText
import info.nightscout.androidaps.setupwizard.elements.SWPlugin
import info.nightscout.androidaps.setupwizard.elements.SWPreference
import info.nightscout.androidaps.setupwizard.elements.SWRadioButton
import info.nightscout.androidaps.setupwizard.events.EventSWUpdate import info.nightscout.androidaps.setupwizard.events.EventSWUpdate
import info.nightscout.androidaps.utils.AndroidPermission
import info.nightscout.androidaps.utils.CryptoUtil import info.nightscout.androidaps.utils.CryptoUtil
import info.nightscout.androidaps.utils.HardLimits import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.extensions.isRunningTest import info.nightscout.androidaps.utils.extensions.isRunningTest
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import java.util.*
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@ -110,7 +128,7 @@ class SWDefinition @Inject constructor(
private val screenPermissionWindow = SWScreen(injector, R.string.permission) private val screenPermissionWindow = SWScreen(injector, R.string.permission)
.skippable(false) .skippable(false)
.add(SWInfoText(injector) .add(SWInfoText(injector)
.label(rh.gs(R.string.needsystemwindowpermission))) .label(rh.gs(R.string.need_system_window_permission)))
.add(SWBreak(injector)) .add(SWBreak(injector))
.add(SWButton(injector) .add(SWButton(injector)
.text(R.string.askforpermission) .text(R.string.askforpermission)
@ -121,7 +139,7 @@ class SWDefinition @Inject constructor(
private val screenPermissionBattery = SWScreen(injector, R.string.permission) private val screenPermissionBattery = SWScreen(injector, R.string.permission)
.skippable(false) .skippable(false)
.add(SWInfoText(injector) .add(SWInfoText(injector)
.label(rh.gs(R.string.needwhitelisting, rh.gs(R.string.app_name)))) .label(rh.gs(R.string.need_whitelisting, rh.gs(R.string.app_name))))
.add(SWBreak(injector)) .add(SWBreak(injector))
.add(SWButton(injector) .add(SWButton(injector)
.text(R.string.askforpermission) .text(R.string.askforpermission)
@ -132,7 +150,7 @@ class SWDefinition @Inject constructor(
private val screenPermissionBt = SWScreen(injector, R.string.permission) private val screenPermissionBt = SWScreen(injector, R.string.permission)
.skippable(false) .skippable(false)
.add(SWInfoText(injector) .add(SWInfoText(injector)
.label(rh.gs(R.string.needlocationpermission))) .label(rh.gs(R.string.need_location_permission)))
.add(SWBreak(injector)) .add(SWBreak(injector))
.add(SWButton(injector) .add(SWButton(injector)
.text(R.string.askforpermission) .text(R.string.askforpermission)
@ -143,7 +161,7 @@ class SWDefinition @Inject constructor(
private val screenPermissionStore = SWScreen(injector, R.string.permission) private val screenPermissionStore = SWScreen(injector, R.string.permission)
.skippable(false) .skippable(false)
.add(SWInfoText(injector) .add(SWInfoText(injector)
.label(rh.gs(R.string.needstoragepermission))) .label(rh.gs(R.string.need_storage_permission)))
.add(SWBreak(injector)) .add(SWBreak(injector))
.add(SWButton(injector) .add(SWButton(injector)
.text(R.string.askforpermission) .text(R.string.askforpermission)

View file

@ -1,167 +0,0 @@
package info.nightscout.androidaps.utils
import android.Manifest
import android.annotation.SuppressLint
import android.bluetooth.BluetoothAdapter
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.PowerManager
import android.provider.Settings
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.DaggerAppCompatActivityWithResult
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.plugins.general.overview.notifications.NotificationWithAction
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.interfaces.ResourceHelper
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class AndroidPermission @Inject constructor(
val rh: ResourceHelper,
val rxBus: RxBus,
val injector: HasAndroidInjector
) {
private var permissionBatteryOptimizationFailed = false
@SuppressLint("BatteryLife")
fun askForPermission(activity: FragmentActivity, permissions: Array<String>) {
var test = false
var testBattery = false
for (s in permissions) {
test = test || ContextCompat.checkSelfPermission(activity, s) != PackageManager.PERMISSION_GRANTED
if (s == Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) {
val powerManager = activity.getSystemService(Context.POWER_SERVICE) as PowerManager
val packageName = activity.packageName
testBattery = testBattery || !powerManager.isIgnoringBatteryOptimizations(packageName)
}
}
if (test) {
if (activity is DaggerAppCompatActivityWithResult)
try {
activity.requestMultiplePermissions.launch(permissions)
} catch (ignored: IllegalStateException) {
ToastUtils.errorToast(activity, rh.gs(R.string.error_asking_for_permissions))
}
}
if (testBattery) {
try {
if (activity is DaggerAppCompatActivityWithResult)
try {
activity.callForBatteryOptimization.launch(null)
} catch (ignored: IllegalStateException) {
ToastUtils.errorToast(activity, rh.gs(R.string.error_asking_for_permissions))
}
} catch (e: ActivityNotFoundException) {
permissionBatteryOptimizationFailed = true
OKDialog.show(activity, rh.gs(R.string.permission), rh.gs(R.string.alert_dialog_permission_battery_optimization_failed)) { activity.recreate() }
}
}
}
fun askForPermission(activity: FragmentActivity, permission: String) = askForPermission(activity, arrayOf(permission))
fun permissionNotGranted(context: Context, permission: String): Boolean {
var selfCheck = ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED
if (permission == Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) {
if (!permissionBatteryOptimizationFailed) {
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
val packageName = context.packageName
selfCheck = selfCheck && powerManager.isIgnoringBatteryOptimizations(packageName)
}
}
return !selfCheck
}
@Synchronized
fun notifyForSMSPermissions(activity: FragmentActivity, smsCommunicatorPlugin: SmsCommunicatorPlugin) {
if (smsCommunicatorPlugin.isEnabled()) {
if (permissionNotGranted(activity, Manifest.permission.RECEIVE_SMS)) {
val notification = NotificationWithAction(injector, Notification.PERMISSION_SMS, rh.gs(R.string.smscommunicator_missingsmspermission), Notification.URGENT)
notification.action(R.string.request) { askForPermission(activity, arrayOf(Manifest.permission.RECEIVE_SMS, Manifest.permission.SEND_SMS, Manifest.permission.RECEIVE_MMS)) }
rxBus.send(EventNewNotification(notification))
} else rxBus.send(EventDismissNotification(Notification.PERMISSION_SMS))
// Following is a bug in Android 8
// if (permissionNotGranted(activity, Manifest.permission.READ_PHONE_STATE)) {
// val notification = NotificationWithAction(injector, Notification.PERMISSION_PHONE_STATE, rh.gs(R.string.smscommunicator_missingphonestatepermission), Notification.URGENT)
// notification.action(R.string.request) { askForPermission(activity, arrayOf(Manifest.permission.READ_PHONE_STATE)) }
// rxBus.send(EventNewNotification(notification))
// } else rxBus.send(EventDismissNotification(Notification.PERMISSION_PHONE_STATE))
}
}
@SuppressLint("MissingPermission")
@Synchronized
fun notifyForBtConnectPermission(activity: FragmentActivity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// Manifest.permission.BLUETOOTH_CONNECT
if (permissionNotGranted(activity, Manifest.permission.BLUETOOTH_CONNECT) || permissionNotGranted(activity, Manifest.permission.BLUETOOTH_SCAN)) {
val notification = NotificationWithAction(injector, Notification.PERMISSION_BT, rh.gs(R.string.needconnectpermission), Notification.URGENT)
notification.action(R.string.request) { askForPermission(activity, arrayOf(Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT)) }
rxBus.send(EventNewNotification(notification))
} else {
activity.startActivity(Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE))
rxBus.send(EventDismissNotification(Notification.PERMISSION_BT))
}
}
}
@Synchronized
fun notifyForBatteryOptimizationPermission(activity: FragmentActivity) {
if (permissionNotGranted(activity, Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)) {
val notification = NotificationWithAction(injector, Notification.PERMISSION_BATTERY, rh.gs(R.string.needwhitelisting, rh.gs(R.string.app_name)), Notification.URGENT)
notification.action(R.string.request) { askForPermission(activity, arrayOf(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)) }
rxBus.send(EventNewNotification(notification))
} else rxBus.send(EventDismissNotification(Notification.PERMISSION_BATTERY))
}
@Synchronized fun notifyForStoragePermission(activity: FragmentActivity) {
if (permissionNotGranted(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
val notification = NotificationWithAction(injector, Notification.PERMISSION_STORAGE, rh.gs(R.string.needstoragepermission), Notification.URGENT)
notification.action(R.string.request) { askForPermission(activity, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)) }
rxBus.send(EventNewNotification(notification))
} else rxBus.send(EventDismissNotification(Notification.PERMISSION_STORAGE))
}
@Synchronized fun notifyForLocationPermissions(activity: FragmentActivity) {
if (permissionNotGranted(activity, Manifest.permission.ACCESS_FINE_LOCATION)) {
val notification = NotificationWithAction(injector, Notification.PERMISSION_LOCATION, rh.gs(R.string.needlocationpermission), Notification.URGENT)
notification.action(R.string.request) { askForPermission(activity, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION)) }
rxBus.send(EventNewNotification(notification))
} else rxBus.send(EventDismissNotification(Notification.PERMISSION_LOCATION))
}
@Synchronized fun notifyForSystemWindowPermissions(activity: FragmentActivity) {
// Check if Android Q or higher
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
if (!Settings.canDrawOverlays(activity)) {
val notification = NotificationWithAction(injector, Notification.PERMISSION_SYSTEM_WINDOW, rh.gs(R.string.needsystemwindowpermission), Notification.URGENT)
notification.action(R.string.request) {
// Check if Android Q or higher
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
// Show alert dialog to the user saying a separate permission is needed
// Launch the settings activity if the user prefers
val intent = Intent(
Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + activity.packageName)
)
activity.startActivity(intent)
}
}
rxBus.send(EventNewNotification(notification))
} else rxBus.send(EventDismissNotification(Notification.PERMISSION_SYSTEM_WINDOW))
}
}
}

View file

@ -67,7 +67,6 @@
<string name="nav_resetdb">Reset Databases</string> <string name="nav_resetdb">Reset Databases</string>
<string name="reset_db_confirm">Do you really want to reset the databases?</string> <string name="reset_db_confirm">Do you really want to reset the databases?</string>
<string name="nav_exit">Exit</string> <string name="nav_exit">Exit</string>
<string name="alert_dialog_permission_battery_optimization_failed">This device does not appear to support battery optimization whitelisting - you may experience performance issues.</string>
<string name="description_actions">Some buttons to quickly access common features</string> <string name="description_actions">Some buttons to quickly access common features</string>
<string name="description_config_builder">Used for configuring the active plugins</string> <string name="description_config_builder">Used for configuring the active plugins</string>
<string name="description_objectives">Learning program</string> <string name="description_objectives">Learning program</string>
@ -225,7 +224,6 @@
<string name="smscommunicator_remotebolusmindistance_summary">Minimum number of minutes that must elapse between one remote bolus and the next</string> <string name="smscommunicator_remotebolusmindistance_summary">Minimum number of minutes that must elapse between one remote bolus and the next</string>
<string name="smscommunicator_remotebolusmindistance">How many minutes must elapse, at least, between one bolus and the next</string> <string name="smscommunicator_remotebolusmindistance">How many minutes must elapse, at least, between one bolus and the next</string>
<string name="smscommunicator_remotebolusmindistance_caveat">For your safety, to edit this preference you need to add at least 2 phone numbers.</string> <string name="smscommunicator_remotebolusmindistance_caveat">For your safety, to edit this preference you need to add at least 2 phone numbers.</string>
<string name="bolusrequested">Going to deliver %1$.2f U</string>
<string name="smscommunicator_bolusdelivered">Bolus %1$.2f U delivered successfully</string> <string name="smscommunicator_bolusdelivered">Bolus %1$.2f U delivered successfully</string>
<string name="smscommunicator_mealbolusdelivered">Meal Bolus %1$.2f U delivered successfully</string> <string name="smscommunicator_mealbolusdelivered">Meal Bolus %1$.2f U delivered successfully</string>
<string name="smscommunicator_mealbolusdelivered_tt">Target %1$s for %2$d minutes</string> <string name="smscommunicator_mealbolusdelivered_tt">Target %1$s for %2$d minutes</string>
@ -295,7 +293,6 @@
<string name="resend_all_data">Resend All Data</string> <string name="resend_all_data">Resend All Data</string>
<string name="open_settings_on_wear">Open Settings on Wear</string> <string name="open_settings_on_wear">Open Settings on Wear</string>
<string name="basal_rate">Basal rate</string> <string name="basal_rate">Basal rate</string>
<string name="basalvaluebelowminimum">Basal value below minimum. Profile not set!</string>
<string name="sms_actualbg">BG:</string> <string name="sms_actualbg">BG:</string>
<string name="sms_lastbg">Last BG:</string> <string name="sms_lastbg">Last BG:</string>
<string name="MM640g">MM640g</string> <string name="MM640g">MM640g</string>
@ -386,7 +383,6 @@
<string name="key_patient_name" translatable="false">patient_name</string> <string name="key_patient_name" translatable="false">patient_name</string>
<string name="key_i_understand" translatable="false">I_understand</string> <string name="key_i_understand" translatable="false">I_understand</string>
<string name="Glimp">Glimp</string> <string name="Glimp">Glimp</string>
<string name="needwhitelisting">%1$s needs battery optimization whitelisting for proper performance</string>
<string name="loopsuspended">Loop suspended</string> <string name="loopsuspended">Loop suspended</string>
<string name="loopsuspendedfor">Suspended (%1$d m)</string> <string name="loopsuspendedfor">Suspended (%1$d m)</string>
<string name="suspendloopfor1h">Suspend loop for 1h</string> <string name="suspendloopfor1h">Suspend loop for 1h</string>
@ -460,7 +456,6 @@
<string name="abs_insulin_shortname">ABS</string> <string name="abs_insulin_shortname">ABS</string>
<string name="devslope_shortname">DEVSLOPE</string> <string name="devslope_shortname">DEVSLOPE</string>
<string name="nav_about">About</string> <string name="nav_about">About</string>
<string name="smscommunicator_missingsmspermission">Missing SMS permission</string>
<string name="smscommunicator_missingphonestatepermission">Missing phone state permission</string> <string name="smscommunicator_missingphonestatepermission">Missing phone state permission</string>
<string name="xdripstatus_settings">xDrip+ Status (watch)</string> <string name="xdripstatus_settings">xDrip+ Status (watch)</string>
<string name="xdripstatus">xDrip+ Statusline (watch)</string> <string name="xdripstatus">xDrip+ Statusline (watch)</string>
@ -551,14 +546,9 @@
<string name="shortenergy">En</string> <string name="shortenergy">En</string>
<string name="shortprotein">Pr</string> <string name="shortprotein">Pr</string>
<string name="shortfat">Fat</string> <string name="shortfat">Fat</string>
<string name="executingrightnow">Command is executed right now</string>
<string name="missed_bg_readings">Missed BG readings</string>
<string name="key_raise_notifications_as_android_notifications" translatable="false">raise_urgent_alarms_as_android_notification</string> <string name="key_raise_notifications_as_android_notifications" translatable="false">raise_urgent_alarms_as_android_notification</string>
<string name="raise_notifications_as_android_notifications">Use system notifications for alerts and notifications</string> <string name="raise_notifications_as_android_notifications">Use system notifications for alerts and notifications</string>
<string name="gradually_increase_notification_volume">Gradually increase the volume for alerts and notifications</string> <string name="gradually_increase_notification_volume">Gradually increase the volume for alerts and notifications</string>
<string name="key_enable_pump_unreachable_alert" translatable="false">enable_pump_unreachable_alert</string>
<string name="key_enable_missed_bg_readings_alert" translatable="false">enable_missed_bg_readings</string>
<string name="key_enable_carbs_required_alert_local" translatable="false">enable_carbs_required_alert_local</string>
<string name="localalertsettings_title">Local alerts</string> <string name="localalertsettings_title">Local alerts</string>
<string name="enable_missed_bg_readings_alert">Alert if no BG data is received</string> <string name="enable_missed_bg_readings_alert">Alert if no BG data is received</string>
<string name="enable_pump_unreachable_alert">Alert if pump is unreachable</string> <string name="enable_pump_unreachable_alert">Alert if pump is unreachable</string>
@ -765,12 +755,7 @@
<string name="setupwizard_pump_waiting_for_riley_link_connection">Please configure your RileyLink below. After selecting a RileyLink, it will be possible to continue setup once the RileyLink status is \"Connected\". This might take a minute.\n</string> <string name="setupwizard_pump_waiting_for_riley_link_connection">Please configure your RileyLink below. After selecting a RileyLink, it will be possible to continue setup once the RileyLink status is \"Connected\". This might take a minute.\n</string>
<string name="setupwizard_pump_pump_not_initialized"><b>Note:</b> You can continue setup once the pump has been set up.\n</string> <string name="setupwizard_pump_pump_not_initialized"><b>Note:</b> You can continue setup once the pump has been set up.\n</string>
<string name="startobjective">Start your first objective</string> <string name="startobjective">Start your first objective</string>
<string name="permission">Permission</string>
<string name="askforpermission">Ask for permission</string> <string name="askforpermission">Ask for permission</string>
<string name="needsystemwindowpermission">Application needs system window permission for notifications</string>
<string name="needlocationpermission">Application needs location permission for BT scan and WiFi identification</string>
<string name="needstoragepermission">Application needs storage permission to be able store log files and export settings</string>
<string name="request">Request</string>
<string name="open_navigation">Open navigation</string> <string name="open_navigation">Open navigation</string>
<string name="close_navigation">Close navigation</string> <string name="close_navigation">Close navigation</string>
<string name="nav_plugin_preferences">Plugin preferences</string> <string name="nav_plugin_preferences">Plugin preferences</string>
@ -1020,7 +1005,6 @@
<string name="filter">Filter</string> <string name="filter">Filter</string>
<string name="copytolocalprofile_invalid">Unable to create profile. Profile is invalid.</string> <string name="copytolocalprofile_invalid">Unable to create profile. Profile is invalid.</string>
<string name="cta_dont_kill_my_app_info">Don\'t kill my app?</string> <string name="cta_dont_kill_my_app_info">Don\'t kill my app?</string>
<string name="key_smscommunicator_report_pump_ureachable" translatable="false">smscommunicator_report_pump_ureachable</string>
<string name="smscommunicator_report_pump_ureachable_summary">Send SMS if unreachable pump event is triggered</string> <string name="smscommunicator_report_pump_ureachable_summary">Send SMS if unreachable pump event is triggered</string>
<string name="smscommunicator_pump_ureachable">Report pump unreachable</string> <string name="smscommunicator_pump_ureachable">Report pump unreachable</string>
<string name="advisoralarm">Run alarm when is time to eat</string> <string name="advisoralarm">Run alarm when is time to eat</string>
@ -1220,7 +1204,6 @@
<string name="blocked_by_charging">Blocked by charging options</string> <string name="blocked_by_charging">Blocked by charging options</string>
<string name="blocked_by_connectivity">Blocked by connectivity options</string> <string name="blocked_by_connectivity">Blocked by connectivity options</string>
<string name="no_watch_connected">(No Watch Connected)</string> <string name="no_watch_connected">(No Watch Connected)</string>
<string name="error_asking_for_permissions">Error asking for permissions</string>
<string name="key_adjust_sensitivity" translatable="false">dynisf_adjust_sensitivity</string> <string name="key_adjust_sensitivity" translatable="false">dynisf_adjust_sensitivity</string>
<string name="dynisf_adjust_sensitivity">Adjust sensitivity and BG</string> <string name="dynisf_adjust_sensitivity">Adjust sensitivity and BG</string>
<string name="database_cleanup">Database cleanup</string> <string name="database_cleanup">Database cleanup</string>

View file

@ -44,7 +44,7 @@
<SwitchPreference <SwitchPreference
android:defaultValue="true" android:defaultValue="true"
android:key="@string/key_smscommunicator_report_pump_ureachable" android:key="@string/key_smscommunicator_report_pump_unreachable"
android:summary="@string/smscommunicator_report_pump_ureachable_summary" android:summary="@string/smscommunicator_report_pump_ureachable_summary"
android:title="@string/smscommunicator_pump_ureachable" /> android:title="@string/smscommunicator_pump_ureachable" />

View file

@ -5,6 +5,7 @@ import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.Constants import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.data.Sms
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePassword
import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult import info.nightscout.androidaps.plugins.general.smsCommunicator.otp.OneTimePasswordValidationResult
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil

View file

@ -8,6 +8,7 @@ import info.nightscout.androidaps.R
import info.nightscout.androidaps.TestBaseWithProfile import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.androidaps.data.IobTotal import info.nightscout.androidaps.data.IobTotal
import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.data.Sms
import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.entities.GlucoseValue import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.database.transactions.CancelCurrentOfflineEventIfAnyTransaction import info.nightscout.androidaps.database.transactions.CancelCurrentOfflineEventIfAnyTransaction

View file

@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.general.smsCommunicator
import android.telephony.SmsMessage import android.telephony.SmsMessage
import info.nightscout.androidaps.TestBase import info.nightscout.androidaps.TestBase
import info.nightscout.androidaps.data.Sms
import org.junit.Assert import org.junit.Assert
import org.junit.Test import org.junit.Test
import org.mockito.Mockito import org.mockito.Mockito

View file

@ -15,6 +15,11 @@ android {
dimension "standard" dimension "standard"
} }
} }
// disable for modules here
buildFeatures {
buildConfig = true
}
} }
dependencies { dependencies {

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.general.smsCommunicator package info.nightscout.androidaps.data
import android.telephony.SmsMessage import android.telephony.SmsMessage
@ -12,21 +12,21 @@ class Sms {
var processed = false var processed = false
var ignored = false var ignored = false
internal constructor(message: SmsMessage) { constructor(message: SmsMessage) {
phoneNumber = message.originatingAddress ?: "" phoneNumber = message.originatingAddress ?: ""
text = message.messageBody text = message.messageBody
date = message.timestampMillis date = message.timestampMillis
received = true received = true
} }
internal constructor(phoneNumber: String, text: String) { constructor(phoneNumber: String, text: String) {
this.phoneNumber = phoneNumber this.phoneNumber = phoneNumber
this.text = text this.text = text
date = System.currentTimeMillis() date = System.currentTimeMillis()
sent = true sent = true
} }
internal constructor(other: Sms, number: String? = null) { constructor(other: Sms, number: String? = null) {
phoneNumber = number ?: other.phoneNumber phoneNumber = number ?: other.phoneNumber
text = other.text text = other.text
date = other.date date = other.date

View file

@ -0,0 +1,17 @@
package info.nightscout.androidaps.interfaces
import android.content.Context
import androidx.fragment.app.FragmentActivity
interface AndroidPermission {
fun askForPermission(activity: FragmentActivity, permissions: Array<String>)
fun askForPermission(activity: FragmentActivity, permission: String) = askForPermission(activity, arrayOf(permission))
fun permissionNotGranted(context: Context, permission: String): Boolean
fun notifyForSMSPermissions(activity: FragmentActivity, smsCommunicator: SmsCommunicator)
fun notifyForBtConnectPermission(activity: FragmentActivity)
fun notifyForBatteryOptimizationPermission(activity: FragmentActivity)
fun notifyForStoragePermission(activity: FragmentActivity)
fun notifyForLocationPermissions(activity: FragmentActivity)
fun notifyForSystemWindowPermissions(activity: FragmentActivity)
}

View file

@ -0,0 +1,10 @@
package info.nightscout.androidaps.interfaces
import info.nightscout.androidaps.data.PumpEnactResult
interface Insight {
fun setTBROverNotification(enabled: Boolean): PumpEnactResult
fun startPump(): PumpEnactResult
fun stopPump(): PumpEnactResult
}

View file

@ -0,0 +1,17 @@
package info.nightscout.androidaps.interfaces
interface LocalAlertUtils {
fun checkPumpUnreachableAlarm(lastConnection: Long, isStatusOutdated: Boolean, isDisconnected: Boolean)
/* Pre-snoozes the alarms with 5 minutes if no snooze exists.
* Call only at startup!
*/
fun preSnoozeAlarms()
/* shortens alarm times in case of setting changes or future data
*/
fun shortenSnoozeInterval()
fun notifyPumpStatusRead()
fun checkStaleBGAlert()
}

View file

@ -1,8 +1,12 @@
package info.nightscout.androidaps.interfaces package info.nightscout.androidaps.interfaces
import androidx.annotation.StringRes
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
interface Overview : ConfigExportImport { interface Overview : ConfigExportImport {
val overviewBus: RxBus val overviewBus: RxBus
fun addNotification(id: Int, text: String, level: Int, @StringRes actionButtonId: Int, action: Runnable)
fun dismissNotification(id: Int)
} }

View file

@ -1,6 +1,9 @@
package info.nightscout.androidaps.interfaces package info.nightscout.androidaps.interfaces
import info.nightscout.androidaps.data.Sms
interface SmsCommunicator { interface SmsCommunicator {
fun sendNotificationToAllNumbers(text: String): Boolean fun sendNotificationToAllNumbers(text: String): Boolean
fun sendSMS(sms: Sms): Boolean
} }

View file

@ -80,6 +80,10 @@
<string name="key_carbs_button_increment_1" translatable="false">carbs_button_increment_1</string> <string name="key_carbs_button_increment_1" translatable="false">carbs_button_increment_1</string>
<string name="key_carbs_button_increment_2" translatable="false">carbs_button_increment_2</string> <string name="key_carbs_button_increment_2" translatable="false">carbs_button_increment_2</string>
<string name="key_carbs_button_increment_3" translatable="false">carbs_button_increment_3</string> <string name="key_carbs_button_increment_3" translatable="false">carbs_button_increment_3</string>
<string name="key_enable_pump_unreachable_alert" translatable="false">enable_pump_unreachable_alert</string>
<string name="key_enable_missed_bg_readings_alert" translatable="false">enable_missed_bg_readings</string>
<string name="key_enable_carbs_required_alert_local" translatable="false">enable_carbs_required_alert_local</string>
<string name="key_smscommunicator_report_pump_unreachable" translatable="false">smscommunicator_report_pump_unreachable</string>
<!-- General--> <!-- General-->
<string name="refresh">Refresh</string> <string name="refresh">Refresh</string>
@ -617,6 +621,9 @@
<string name="autotune_run_cancelled">Another run of Autotune is detected, run cancelled</string> <string name="autotune_run_cancelled">Another run of Autotune is detected, run cancelled</string>
<string name="needconnectpermission">Application needs bluetooth permission</string> <string name="needconnectpermission">Application needs bluetooth permission</string>
<!-- SmsCommunicator -->
<string name="smscommunicator_missingsmspermission">Missing SMS permission</string>
<plurals name="days"> <plurals name="days">
<item quantity="one">%1$d day</item> <item quantity="one">%1$d day</item>
<item quantity="other">%1$d days</item> <item quantity="other">%1$d days</item>

View file

@ -0,0 +1,185 @@
package info.nightscout.implementation
import android.Manifest
import android.annotation.SuppressLint
import android.bluetooth.BluetoothAdapter
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.PowerManager
import android.provider.Settings
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.activities.DaggerAppCompatActivityWithResult
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.AndroidPermission
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.interfaces.SmsCommunicator
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class AndroidPermissionImpl @Inject constructor(
val rh: ResourceHelper,
val rxBus: RxBus,
val injector: HasAndroidInjector,
val activePlugin: ActivePlugin
) : AndroidPermission {
private var permissionBatteryOptimizationFailed = false
@SuppressLint("BatteryLife")
override fun askForPermission(activity: FragmentActivity, permissions: Array<String>) {
var test = false
var testBattery = false
for (s in permissions) {
test = test || ContextCompat.checkSelfPermission(activity, s) != PackageManager.PERMISSION_GRANTED
if (s == Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) {
val powerManager = activity.getSystemService(Context.POWER_SERVICE) as PowerManager
val packageName = activity.packageName
testBattery = testBattery || !powerManager.isIgnoringBatteryOptimizations(packageName)
}
}
if (test) {
if (activity is DaggerAppCompatActivityWithResult)
try {
activity.requestMultiplePermissions.launch(permissions)
} catch (ignored: IllegalStateException) {
ToastUtils.errorToast(activity, rh.gs(R.string.error_asking_for_permissions))
}
}
if (testBattery) {
try {
if (activity is DaggerAppCompatActivityWithResult)
try {
activity.callForBatteryOptimization.launch(null)
} catch (ignored: IllegalStateException) {
ToastUtils.errorToast(activity, rh.gs(R.string.error_asking_for_permissions))
}
} catch (e: ActivityNotFoundException) {
permissionBatteryOptimizationFailed = true
OKDialog.show(activity, rh.gs(R.string.permission), rh.gs(R.string.alert_dialog_permission_battery_optimization_failed)) { activity.recreate() }
}
}
}
override fun askForPermission(activity: FragmentActivity, permission: String) = askForPermission(activity, arrayOf(permission))
override fun permissionNotGranted(context: Context, permission: String): Boolean {
var selfCheck = ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED
if (permission == Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS) {
if (!permissionBatteryOptimizationFailed) {
val powerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
val packageName = context.packageName
selfCheck = selfCheck && powerManager.isIgnoringBatteryOptimizations(packageName)
}
}
return !selfCheck
}
@Synchronized
override fun notifyForSMSPermissions(activity: FragmentActivity, smsCommunicator: SmsCommunicator) {
if ((smsCommunicator as PluginBase).isEnabled()) {
if (permissionNotGranted(activity, Manifest.permission.RECEIVE_SMS))
activePlugin.activeOverview.addNotification(
id = Notification.PERMISSION_SMS,
text = rh.gs(R.string.smscommunicator_missingsmspermission),
level = Notification.URGENT,
actionButtonId = R.string.request
) {
askForPermission(
activity,
arrayOf(Manifest.permission.RECEIVE_SMS, Manifest.permission.SEND_SMS, Manifest.permission.RECEIVE_MMS)
)
}
else activePlugin.activeOverview.dismissNotification(Notification.PERMISSION_SMS)
}
}
@SuppressLint("MissingPermission")
@Synchronized
override fun notifyForBtConnectPermission(activity: FragmentActivity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// Manifest.permission.BLUETOOTH_CONNECT
if (permissionNotGranted(activity, Manifest.permission.BLUETOOTH_CONNECT) || permissionNotGranted(activity, Manifest.permission.BLUETOOTH_SCAN))
activePlugin.activeOverview.addNotification(
id = Notification.PERMISSION_BT,
text = rh.gs(R.string.needconnectpermission),
level = Notification.URGENT,
actionButtonId = R.string.request
) { askForPermission(activity, arrayOf(Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT)) }
else {
activity.startActivity(Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE))
activePlugin.activeOverview.dismissNotification(Notification.PERMISSION_BT)
}
}
}
@Synchronized
override fun notifyForBatteryOptimizationPermission(activity: FragmentActivity) {
if (permissionNotGranted(activity, Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS))
activePlugin.activeOverview.addNotification(
id = Notification.PERMISSION_BATTERY,
text = rh.gs(R.string.need_whitelisting, rh.gs(R.string.app_name)),
level = Notification.URGENT,
actionButtonId = R.string.request
) { askForPermission(activity, arrayOf(Manifest.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)) }
else activePlugin.activeOverview.dismissNotification(Notification.PERMISSION_BATTERY)
}
@Synchronized override fun notifyForStoragePermission(activity: FragmentActivity) {
if (permissionNotGranted(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE))
activePlugin.activeOverview.addNotification(
id = Notification.PERMISSION_STORAGE,
text = rh.gs(R.string.need_storage_permission),
level = Notification.URGENT,
actionButtonId = R.string.request
) { askForPermission(activity, arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE)) }
else activePlugin.activeOverview.dismissNotification(Notification.PERMISSION_STORAGE)
}
@Synchronized override fun notifyForLocationPermissions(activity: FragmentActivity) {
if (permissionNotGranted(activity, Manifest.permission.ACCESS_FINE_LOCATION)) {
activePlugin.activeOverview.addNotification(
id = Notification.PERMISSION_LOCATION,
text = rh.gs(R.string.need_location_permission),
level = Notification.URGENT,
actionButtonId = R.string.request
) { askForPermission(activity, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION)) }
} else activePlugin.activeOverview.dismissNotification(Notification.PERMISSION_LOCATION)
}
@Synchronized override fun notifyForSystemWindowPermissions(activity: FragmentActivity) {
// Check if Android Q or higher
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
if (!Settings.canDrawOverlays(activity))
activePlugin.activeOverview.addNotification(
id = Notification.PERMISSION_SYSTEM_WINDOW,
text = rh.gs(R.string.need_location_permission),
level = Notification.URGENT,
actionButtonId = R.string.request
) {
// Check if Android Q or higher
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.P) {
// Show alert dialog to the user saying a separate permission is needed
// Launch the settings activity if the user prefers
val intent = Intent(
Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + activity.packageName)
)
activity.startActivity(intent)
}
}
else activePlugin.activeOverview.dismissNotification(Notification.PERMISSION_SYSTEM_WINDOW)
}
}
}

View file

@ -1,7 +1,6 @@
package info.nightscout.androidaps.utils package info.nightscout.implementation
import info.nightscout.androidaps.Constants import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.database.entities.TherapyEvent import info.nightscout.androidaps.database.entities.TherapyEvent
@ -11,14 +10,17 @@ import info.nightscout.androidaps.database.entities.ValueWithUnit
import info.nightscout.androidaps.database.transactions.InsertTherapyEventAnnouncementTransaction import info.nightscout.androidaps.database.transactions.InsertTherapyEventAnnouncementTransaction
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.LocalAlertUtils
import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.interfaces.SmsCommunicator
import info.nightscout.androidaps.logging.UserEntryLogger import info.nightscout.androidaps.logging.UserEntryLogger
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.T
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag import info.nightscout.shared.logging.LTag
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
@ -32,19 +34,19 @@ import kotlin.math.min
* Created by adrian on 17/12/17. * Created by adrian on 17/12/17.
*/ */
@Singleton @Singleton
class LocalAlertUtils @Inject constructor( class LocalAlertUtilsImpl @Inject constructor(
private val aapsLogger: AAPSLogger, private val aapsLogger: AAPSLogger,
private val sp: SP, private val sp: SP,
private val rxBus: RxBus, private val rxBus: RxBus,
private val rh: ResourceHelper, private val rh: ResourceHelper,
private val activePlugin: ActivePlugin, private val activePlugin: ActivePlugin,
private val profileFunction: ProfileFunction, private val profileFunction: ProfileFunction,
private val smsCommunicatorPlugin: SmsCommunicatorPlugin, private val smsCommunicatorPlugin: SmsCommunicator,
private val config: Config, private val config: Config,
private val repository: AppRepository, private val repository: AppRepository,
private val dateUtil: DateUtil, private val dateUtil: DateUtil,
private val uel: UserEntryLogger private val uel: UserEntryLogger
) { ) : LocalAlertUtils {
private val disposable = CompositeDisposable() private val disposable = CompositeDisposable()
@ -56,7 +58,7 @@ class LocalAlertUtils @Inject constructor(
return T.mins(sp.getInt(R.string.key_pump_unreachable_threshold_minutes, Constants.DEFAULT_PUMP_UNREACHABLE_THRESHOLD_MINUTES).toLong()).msecs() return T.mins(sp.getInt(R.string.key_pump_unreachable_threshold_minutes, Constants.DEFAULT_PUMP_UNREACHABLE_THRESHOLD_MINUTES).toLong()).msecs()
} }
fun checkPumpUnreachableAlarm(lastConnection: Long, isStatusOutdated: Boolean, isDisconnected: Boolean) { override fun checkPumpUnreachableAlarm(lastConnection: Long, isStatusOutdated: Boolean, isDisconnected: Boolean) {
val alarmTimeoutExpired = isAlarmTimeoutExpired(lastConnection, pumpUnreachableThreshold()) val alarmTimeoutExpired = isAlarmTimeoutExpired(lastConnection, pumpUnreachableThreshold())
val nextAlarmOccurrenceReached = sp.getLong("nextPumpDisconnectedAlarm", 0L) < System.currentTimeMillis() val nextAlarmOccurrenceReached = sp.getLong("nextPumpDisconnectedAlarm", 0L) < System.currentTimeMillis()
if (config.APS && isStatusOutdated && alarmTimeoutExpired && nextAlarmOccurrenceReached && !isDisconnected) { if (config.APS && isStatusOutdated && alarmTimeoutExpired && nextAlarmOccurrenceReached && !isDisconnected) {
@ -68,7 +70,7 @@ class LocalAlertUtils @Inject constructor(
if (sp.getBoolean(R.string.key_ns_create_announcements_from_errors, true)) if (sp.getBoolean(R.string.key_ns_create_announcements_from_errors, true))
disposable += repository.runTransaction(InsertTherapyEventAnnouncementTransaction(rh.gs(R.string.pump_unreachable))).subscribe() disposable += repository.runTransaction(InsertTherapyEventAnnouncementTransaction(rh.gs(R.string.pump_unreachable))).subscribe()
} }
if (sp.getBoolean(R.string.key_smscommunicator_report_pump_ureachable, true)) if (sp.getBoolean(R.string.key_smscommunicator_report_pump_unreachable, true))
smsCommunicatorPlugin.sendNotificationToAllNumbers(rh.gs(R.string.pump_unreachable)) smsCommunicatorPlugin.sendNotificationToAllNumbers(rh.gs(R.string.pump_unreachable))
} }
if (!isStatusOutdated && !alarmTimeoutExpired) rxBus.send(EventDismissNotification(Notification.PUMP_UNREACHABLE)) if (!isStatusOutdated && !alarmTimeoutExpired) rxBus.send(EventDismissNotification(Notification.PUMP_UNREACHABLE))
@ -85,7 +87,7 @@ class LocalAlertUtils @Inject constructor(
/*Pre-snoozes the alarms with 5 minutes if no snooze exists. /*Pre-snoozes the alarms with 5 minutes if no snooze exists.
* Call only at startup! * Call only at startup!
*/ */
fun preSnoozeAlarms() { override fun preSnoozeAlarms() {
if (sp.getLong("nextMissedReadingsAlarm", 0L) < System.currentTimeMillis()) { if (sp.getLong("nextMissedReadingsAlarm", 0L) < System.currentTimeMillis()) {
sp.putLong("nextMissedReadingsAlarm", System.currentTimeMillis() + 5 * 60 * 1000) sp.putLong("nextMissedReadingsAlarm", System.currentTimeMillis() + 5 * 60 * 1000)
} }
@ -94,7 +96,7 @@ class LocalAlertUtils @Inject constructor(
} }
} }
fun shortenSnoozeInterval() { //shortens alarm times in case of setting changes or future data override fun shortenSnoozeInterval() { //shortens alarm times in case of setting changes or future data
var nextMissedReadingsAlarm = sp.getLong("nextMissedReadingsAlarm", 0L) var nextMissedReadingsAlarm = sp.getLong("nextMissedReadingsAlarm", 0L)
nextMissedReadingsAlarm = min(System.currentTimeMillis() + missedReadingsThreshold(), nextMissedReadingsAlarm) nextMissedReadingsAlarm = min(System.currentTimeMillis() + missedReadingsThreshold(), nextMissedReadingsAlarm)
sp.putLong("nextMissedReadingsAlarm", nextMissedReadingsAlarm) sp.putLong("nextMissedReadingsAlarm", nextMissedReadingsAlarm)
@ -103,7 +105,7 @@ class LocalAlertUtils @Inject constructor(
sp.putLong("nextPumpDisconnectedAlarm", nextPumpDisconnectedAlarm) sp.putLong("nextPumpDisconnectedAlarm", nextPumpDisconnectedAlarm)
} }
fun notifyPumpStatusRead() { //TODO: persist the actual time the pump is read and simplify the whole logic when to alarm override fun notifyPumpStatusRead() { //TODO: persist the actual time the pump is read and simplify the whole logic when to alarm
val pump = activePlugin.activePump val pump = activePlugin.activePump
val profile = profileFunction.getProfile() val profile = profileFunction.getProfile()
if (profile != null) { if (profile != null) {
@ -115,7 +117,7 @@ class LocalAlertUtils @Inject constructor(
} }
} }
fun checkStaleBGAlert() { override fun checkStaleBGAlert() {
val bgReadingWrapped = repository.getLastGlucoseValueWrapped().blockingGet() val bgReadingWrapped = repository.getLastGlucoseValueWrapped().blockingGet()
val bgReading = if (bgReadingWrapped is ValueWrapper.Existing) bgReadingWrapped.value else return val bgReading = if (bgReadingWrapped is ValueWrapper.Existing) bgReadingWrapped.value else return
if (sp.getBoolean(R.string.key_enable_missed_bg_readings_alert, false) if (sp.getBoolean(R.string.key_enable_missed_bg_readings_alert, false)

View file

@ -1,9 +1,25 @@
package info.nightscout.androidaps.di package info.nightscout.implementation.di
import dagger.Module import dagger.Module
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.queue.CommandQueueImplementation import info.nightscout.implementation.queue.CommandQueueImplementation
import info.nightscout.androidaps.queue.commands.* import info.nightscout.implementation.queue.commands.CommandReadStatus
import info.nightscout.implementation.queue.commands.CommandSMBBolus
import info.nightscout.implementation.queue.commands.CommandSetProfile
import info.nightscout.implementation.queue.commands.CommandSetUserSettings
import info.nightscout.implementation.queue.commands.CommandStartPump
import info.nightscout.implementation.queue.commands.CommandStopPump
import info.nightscout.implementation.queue.commands.CommandTempBasalAbsolute
import info.nightscout.implementation.queue.commands.CommandTempBasalPercent
import info.nightscout.implementation.queue.commands.CommandBolus
import info.nightscout.implementation.queue.commands.CommandCancelExtendedBolus
import info.nightscout.implementation.queue.commands.CommandCancelTempBasal
import info.nightscout.implementation.queue.commands.CommandCustomCommand
import info.nightscout.implementation.queue.commands.CommandExtendedBolus
import info.nightscout.implementation.queue.commands.CommandInsightSetTBROverNotification
import info.nightscout.implementation.queue.commands.CommandLoadEvents
import info.nightscout.implementation.queue.commands.CommandLoadHistory
import info.nightscout.implementation.queue.commands.CommandLoadTDDs
@Module @Module
@Suppress("unused") @Suppress("unused")

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.queue package info.nightscout.implementation.queue
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
@ -6,7 +6,6 @@ import android.os.SystemClock
import android.text.Spanned import android.text.Spanned
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.BolusProgressHelperActivity import info.nightscout.androidaps.activities.BolusProgressHelperActivity
import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.activities.ErrorHelperActivity
import info.nightscout.androidaps.annotations.OpenForTesting import info.nightscout.androidaps.annotations.OpenForTesting
@ -22,22 +21,48 @@ import info.nightscout.androidaps.dialogs.BolusProgressDialog
import info.nightscout.androidaps.events.EventMobileToWear import info.nightscout.androidaps.events.EventMobileToWear
import info.nightscout.androidaps.events.EventProfileSwitchChanged import info.nightscout.androidaps.events.EventProfileSwitchChanged
import info.nightscout.androidaps.extensions.getCustomizedName import info.nightscout.androidaps.extensions.getCustomizedName
import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.AndroidPermission
import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.interfaces.CommandQueue
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissBolusProgressIfRunning import info.nightscout.androidaps.plugins.general.overview.events.EventDismissBolusProgressIfRunning
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.queue.commands.* import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.androidaps.queue.commands.Command.CommandType import info.nightscout.androidaps.queue.commands.Command.CommandType
import info.nightscout.androidaps.utils.AndroidPermission import info.nightscout.androidaps.queue.commands.CustomCommand
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.HtmlHelper import info.nightscout.androidaps.utils.HtmlHelper
import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.implementation.R
import info.nightscout.implementation.queue.commands.CommandBolus
import info.nightscout.implementation.queue.commands.CommandCancelExtendedBolus
import info.nightscout.implementation.queue.commands.CommandCancelTempBasal
import info.nightscout.implementation.queue.commands.CommandCustomCommand
import info.nightscout.implementation.queue.commands.CommandExtendedBolus
import info.nightscout.implementation.queue.commands.CommandInsightSetTBROverNotification
import info.nightscout.implementation.queue.commands.CommandLoadEvents
import info.nightscout.implementation.queue.commands.CommandLoadHistory
import info.nightscout.implementation.queue.commands.CommandLoadTDDs
import info.nightscout.implementation.queue.commands.CommandReadStatus
import info.nightscout.implementation.queue.commands.CommandSMBBolus
import info.nightscout.implementation.queue.commands.CommandSetProfile
import info.nightscout.implementation.queue.commands.CommandSetUserSettings
import info.nightscout.implementation.queue.commands.CommandStartPump
import info.nightscout.implementation.queue.commands.CommandStopPump
import info.nightscout.implementation.queue.commands.CommandTempBasalAbsolute
import info.nightscout.implementation.queue.commands.CommandTempBasalPercent
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag import info.nightscout.shared.logging.LTag
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
@ -45,7 +70,7 @@ import info.nightscout.shared.weardata.EventData
import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.kotlin.plusAssign import io.reactivex.rxjava3.kotlin.plusAssign
import io.reactivex.rxjava3.kotlin.subscribeBy import io.reactivex.rxjava3.kotlin.subscribeBy
import java.util.* import java.util.LinkedList
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@ -121,7 +146,7 @@ class CommandQueueImplementation @Inject constructor(
} }
private fun executingNowError(): PumpEnactResult = private fun executingNowError(): PumpEnactResult =
PumpEnactResult(injector).success(false).enacted(false).comment(R.string.executingrightnow) PumpEnactResult(injector).success(false).enacted(false).comment(R.string.executing_right_now)
override fun isRunning(type: CommandType): Boolean = performing?.commandType == type override fun isRunning(type: CommandType): Boolean = performing?.commandType == type
@ -300,7 +325,7 @@ class CommandQueueImplementation @Inject constructor(
// not when the Bolus command is starting. The command closes the dialog upon completion). // not when the Bolus command is starting. The command closes the dialog upon completion).
showBolusProgressDialog(detailedBolusInfo) showBolusProgressDialog(detailedBolusInfo)
// Notify Wear about upcoming bolus // Notify Wear about upcoming bolus
rxBus.send(EventMobileToWear(EventData.BolusProgress(percent = 0, status = rh.gs(R.string.bolusrequested, detailedBolusInfo.insulin)))) rxBus.send(EventMobileToWear(EventData.BolusProgress(percent = 0, status = rh.gs(R.string.goingtodeliver, detailedBolusInfo.insulin))))
} }
} }
notifyAboutNewCommand() notifyAboutNewCommand()
@ -421,9 +446,9 @@ class CommandQueueImplementation @Inject constructor(
val basalValues = profile.getBasalValues() val basalValues = profile.getBasalValues()
for (basalValue in basalValues) { for (basalValue in basalValues) {
if (basalValue.value < activePlugin.activePump.pumpDescription.basalMinimumRate) { if (basalValue.value < activePlugin.activePump.pumpDescription.basalMinimumRate) {
val notification = Notification(Notification.BASAL_VALUE_BELOW_MINIMUM, rh.gs(R.string.basalvaluebelowminimum), Notification.URGENT) val notification = Notification(Notification.BASAL_VALUE_BELOW_MINIMUM, rh.gs(R.string.basal_value_below_minimum), Notification.URGENT)
rxBus.send(EventNewNotification(notification)) rxBus.send(EventNewNotification(notification))
callback?.result(PumpEnactResult(injector).success(false).enacted(false).comment(R.string.basalvaluebelowminimum))?.run() callback?.result(PumpEnactResult(injector).success(false).enacted(false).comment(R.string.basal_value_below_minimum))?.run()
return false return false
} }
} }

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.queue package info.nightscout.implementation.queue
import android.bluetooth.BluetoothManager import android.bluetooth.BluetoothManager
import android.content.Context import android.content.Context
@ -6,19 +6,19 @@ import android.os.Build
import android.os.PowerManager import android.os.PowerManager
import android.os.SystemClock import android.os.SystemClock
import info.nightscout.androidaps.Constants import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.R
import info.nightscout.androidaps.events.EventPumpStatusChanged import info.nightscout.androidaps.events.EventPumpStatusChanged
import info.nightscout.androidaps.extensions.safeDisable import info.nightscout.androidaps.extensions.safeDisable
import info.nightscout.androidaps.extensions.safeEnable import info.nightscout.androidaps.extensions.safeEnable
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.AndroidPermission
import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.CommandQueue
import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissBolusProgressIfRunning import info.nightscout.androidaps.plugins.general.overview.events.EventDismissBolusProgressIfRunning
import info.nightscout.androidaps.queue.events.EventQueueChanged import info.nightscout.androidaps.queue.events.EventQueueChanged
import info.nightscout.androidaps.utils.AndroidPermission
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.implementation.R
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.logging.LTag import info.nightscout.shared.logging.LTag
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP

View file

@ -1,14 +1,15 @@
package info.nightscout.androidaps.queue.commands package info.nightscout.implementation.queue.commands
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.dialogs.BolusProgressDialog import info.nightscout.androidaps.dialogs.BolusProgressDialog
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissBolusProgressIfRunning import info.nightscout.androidaps.plugins.general.overview.events.EventDismissBolusProgressIfRunning
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.implementation.R
import info.nightscout.shared.logging.LTag
import javax.inject.Inject import javax.inject.Inject
class CommandBolus( class CommandBolus(

View file

@ -1,10 +1,11 @@
package info.nightscout.androidaps.queue.commands package info.nightscout.implementation.queue.commands
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.implementation.R
import info.nightscout.shared.logging.LTag
import javax.inject.Inject import javax.inject.Inject
class CommandCancelExtendedBolus constructor( class CommandCancelExtendedBolus constructor(

View file

@ -1,10 +1,11 @@
package info.nightscout.androidaps.queue.commands package info.nightscout.implementation.queue.commands
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.implementation.R
import info.nightscout.shared.logging.LTag
import javax.inject.Inject import javax.inject.Inject
class CommandCancelTempBasal( class CommandCancelTempBasal(

View file

@ -1,9 +1,11 @@
package info.nightscout.androidaps.queue.commands package info.nightscout.implementation.queue.commands
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.androidaps.queue.commands.CustomCommand
import info.nightscout.shared.logging.LTag
import javax.inject.Inject import javax.inject.Inject
class CommandCustomCommand( class CommandCustomCommand(

View file

@ -1,10 +1,11 @@
package info.nightscout.androidaps.queue.commands package info.nightscout.implementation.queue.commands
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.implementation.R
import info.nightscout.shared.logging.LTag
import javax.inject.Inject import javax.inject.Inject
class CommandExtendedBolus constructor( class CommandExtendedBolus constructor(

View file

@ -1,10 +1,11 @@
package info.nightscout.androidaps.queue.commands package info.nightscout.implementation.queue.commands
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin import info.nightscout.androidaps.interfaces.Insight
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.implementation.R
import javax.inject.Inject import javax.inject.Inject
class CommandInsightSetTBROverNotification constructor( class CommandInsightSetTBROverNotification constructor(
@ -17,14 +18,14 @@ class CommandInsightSetTBROverNotification constructor(
override fun execute() { override fun execute() {
val pump = activePlugin.activePump val pump = activePlugin.activePump
if (pump is LocalInsightPlugin) { if (pump is Insight) {
val result = pump.setTBROverNotification(enabled) val result = pump.setTBROverNotification(enabled)
callback?.result(result)?.run() callback?.result(result)?.run()
} }
} }
@Suppress("SpellCheckingInspection")
override fun status(): String = rh.gs(R.string.insight_set_tbr_over_notification) override fun status(): String = rh.gs(R.string.insight_set_tbr_over_notification)
@Suppress("SpellCheckingInspection")
override fun log(): String = "INSIGHTSETTBROVERNOTIFICATION" override fun log(): String = "INSIGHTSETTBROVERNOTIFICATION"
} }

View file

@ -1,12 +1,13 @@
package info.nightscout.androidaps.queue.commands package info.nightscout.implementation.queue.commands
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.Dana import info.nightscout.androidaps.interfaces.Dana
import info.nightscout.androidaps.interfaces.Diaconn import info.nightscout.androidaps.interfaces.Diaconn
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.implementation.R
import info.nightscout.shared.logging.LTag
import javax.inject.Inject import javax.inject.Inject
class CommandLoadEvents( class CommandLoadEvents(

View file

@ -1,12 +1,13 @@
package info.nightscout.androidaps.queue.commands package info.nightscout.implementation.queue.commands
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.Dana import info.nightscout.androidaps.interfaces.Dana
import info.nightscout.androidaps.interfaces.Diaconn import info.nightscout.androidaps.interfaces.Diaconn
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.implementation.R
import info.nightscout.shared.logging.LTag
import javax.inject.Inject import javax.inject.Inject
class CommandLoadHistory( class CommandLoadHistory(

View file

@ -1,10 +1,11 @@
package info.nightscout.androidaps.queue.commands package info.nightscout.implementation.queue.commands
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.implementation.R
import info.nightscout.shared.logging.LTag
import javax.inject.Inject import javax.inject.Inject
class CommandLoadTDDs( class CommandLoadTDDs(

View file

@ -1,13 +1,14 @@
package info.nightscout.androidaps.queue.commands package info.nightscout.implementation.queue.commands
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.interfaces.LocalAlertUtils
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.LocalAlertUtils import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.implementation.R
import info.nightscout.shared.logging.LTag
import javax.inject.Inject import javax.inject.Inject
class CommandReadStatus( class CommandReadStatus(

View file

@ -1,14 +1,15 @@
package info.nightscout.androidaps.queue.commands package info.nightscout.implementation.queue.commands
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import info.nightscout.implementation.R
import info.nightscout.shared.logging.LTag
import javax.inject.Inject import javax.inject.Inject
class CommandSMBBolus( class CommandSMBBolus(

View file

@ -1,17 +1,19 @@
package info.nightscout.androidaps.queue.commands package info.nightscout.implementation.queue.commands
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.database.ValueWrapper import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.CommandQueue
import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.shared.logging.LTag import info.nightscout.androidaps.interfaces.SmsCommunicator
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.implementation.R
import info.nightscout.shared.logging.LTag
import javax.inject.Inject import javax.inject.Inject
class CommandSetProfile constructor( class CommandSetProfile constructor(
@ -21,7 +23,7 @@ class CommandSetProfile constructor(
callback: Callback? callback: Callback?
) : Command(injector, CommandType.BASAL_PROFILE, callback) { ) : Command(injector, CommandType.BASAL_PROFILE, callback) {
@Inject lateinit var smsCommunicatorPlugin: SmsCommunicatorPlugin @Inject lateinit var smsCommunicatorPlugin: SmsCommunicator
@Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var activePlugin: ActivePlugin
@Inject lateinit var dateUtil: DateUtil @Inject lateinit var dateUtil: DateUtil
@Inject lateinit var commandQueue: CommandQueue @Inject lateinit var commandQueue: CommandQueue
@ -39,7 +41,7 @@ class CommandSetProfile constructor(
// Send SMS notification if ProfileSwitch is coming from NS // Send SMS notification if ProfileSwitch is coming from NS
val profileSwitch = repository.getEffectiveProfileSwitchActiveAt(dateUtil.now()).blockingGet() val profileSwitch = repository.getEffectiveProfileSwitchActiveAt(dateUtil.now()).blockingGet()
if (profileSwitch is ValueWrapper.Existing && r.enacted && hasNsId && !config.NSCLIENT) { if (profileSwitch is ValueWrapper.Existing && r.enacted && hasNsId && !config.NSCLIENT) {
if (smsCommunicatorPlugin.isEnabled()) if ((smsCommunicatorPlugin as PluginBase).isEnabled())
smsCommunicatorPlugin.sendNotificationToAllNumbers(rh.gs(R.string.profile_set_ok)) smsCommunicatorPlugin.sendNotificationToAllNumbers(rh.gs(R.string.profile_set_ok))
} }
} }

View file

@ -1,12 +1,13 @@
package info.nightscout.androidaps.queue.commands package info.nightscout.implementation.queue.commands
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.Dana import info.nightscout.androidaps.interfaces.Dana
import info.nightscout.androidaps.interfaces.Diaconn import info.nightscout.androidaps.interfaces.Diaconn
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.implementation.R
import info.nightscout.shared.logging.LTag
import javax.inject.Inject import javax.inject.Inject
class CommandSetUserSettings( class CommandSetUserSettings(

View file

@ -1,10 +1,11 @@
package info.nightscout.androidaps.queue.commands package info.nightscout.implementation.queue.commands
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin import info.nightscout.androidaps.interfaces.Insight
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.implementation.R
import javax.inject.Inject import javax.inject.Inject
class CommandStartPump( class CommandStartPump(
@ -16,7 +17,7 @@ class CommandStartPump(
override fun execute() { override fun execute() {
val pump = activePlugin.activePump val pump = activePlugin.activePump
if (pump is LocalInsightPlugin) { if (pump is Insight) {
val result = pump.startPump() val result = pump.startPump()
callback?.result(result)?.run() callback?.result(result)?.run()
} }

View file

@ -1,10 +1,11 @@
package info.nightscout.androidaps.queue.commands package info.nightscout.implementation.queue.commands
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin import info.nightscout.androidaps.interfaces.Insight
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.implementation.R
import javax.inject.Inject import javax.inject.Inject
class CommandStopPump( class CommandStopPump(
@ -16,7 +17,7 @@ class CommandStopPump(
override fun execute() { override fun execute() {
val pump = activePlugin.activePump val pump = activePlugin.activePump
if (pump is LocalInsightPlugin) { if (pump is Insight) {
val result = pump.stopPump() val result = pump.stopPump()
callback?.result(result)?.run() callback?.result(result)?.run()
} }

View file

@ -1,12 +1,13 @@
package info.nightscout.androidaps.queue.commands package info.nightscout.implementation.queue.commands
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.PumpSync import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.implementation.R
import info.nightscout.shared.logging.LTag
import javax.inject.Inject import javax.inject.Inject
class CommandTempBasalAbsolute( class CommandTempBasalAbsolute(

View file

@ -1,12 +1,13 @@
package info.nightscout.androidaps.queue.commands package info.nightscout.implementation.queue.commands
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.interfaces.PumpSync import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.shared.logging.LTag
import info.nightscout.androidaps.queue.Callback import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.implementation.R
import info.nightscout.shared.logging.LTag
import javax.inject.Inject import javax.inject.Inject
class CommandTempBasalPercent( class CommandTempBasalPercent(

View file

@ -4,6 +4,7 @@
<string name="calibration_sent">Calibration sent to xDrip+</string> <string name="calibration_sent">Calibration sent to xDrip+</string>
<string name="bg_label">BG</string> <string name="bg_label">BG</string>
<string name="missed_bg_readings">Missed BG readings</string>
<string name="time_to_eat">Time to eat</string> <string name="time_to_eat">Time to eat</string>
<string name="enable_bolus_advisor">Enable bolus advisor</string> <string name="enable_bolus_advisor">Enable bolus advisor</string>
@ -11,5 +12,15 @@
<string name="bolus_advisor">Bolus advisor</string> <string name="bolus_advisor">Bolus advisor</string>
<string name="bolus_advisor_message">You have high glycemia. Instead of eating now it\'s recommended to wait for better glycemia. Do you want to do a correction bolus now and remind you when it\'s time to eat? In this case no carbs will be recorded and you must use wizard again when we remind you.</string> <string name="bolus_advisor_message">You have high glycemia. Instead of eating now it\'s recommended to wait for better glycemia. Do you want to do a correction bolus now and remind you when it\'s time to eat? In this case no carbs will be recorded and you must use wizard again when we remind you.</string>
<string name="time_to_bolus">Time to bolus!\nRun Bolus wizard and do calculation again.</string> <string name="time_to_bolus">Time to bolus!\nRun Bolus wizard and do calculation again.</string>
<string name="executing_right_now">Command is executed right now</string>
<string name="basal_value_below_minimum">Basal value below minimum. Profile not set!</string>
<string name="request">Request</string>
<string name="permission">Permission</string>
<string name="need_whitelisting">%1$s needs battery optimization whitelisting for proper performance</string>
<string name="need_system_window_permission">Application needs system window permission for notifications</string>
<string name="need_location_permission">Application needs location permission for BT scan and WiFi identification</string>
<string name="need_storage_permission">Application needs storage permission to be able store log files and export settings</string>
<string name="error_asking_for_permissions">Error asking for permissions</string>
<string name="alert_dialog_permission_battery_optimization_failed">This device does not appear to support battery optimization whitelisting - you may experience performance issues.</string>
</resources> </resources>

View file

@ -0,0 +1,177 @@
package info.nightscout.androidaps
import android.content.Context
import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.ProfileSealed
import info.nightscout.androidaps.database.embedments.InsulinConfiguration
import info.nightscout.androidaps.database.entities.EffectiveProfileSwitch
import info.nightscout.androidaps.extensions.pureProfileFromJson
import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.IobCobCalculator
import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.ProfileStore
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.interfaces.ResourceHelper
import org.json.JSONObject
import org.junit.Before
import org.mockito.ArgumentMatchers.anyDouble
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.`when`
import org.mockito.invocation.InvocationOnMock
@Suppress("SpellCheckingInspection")
open class TestBaseWithProfile : TestBase() {
@Mock lateinit var activePluginProvider: ActivePlugin
@Mock lateinit var rh: ResourceHelper
@Mock lateinit var iobCobCalculator: IobCobCalculator
@Mock lateinit var fabricPrivacy: FabricPrivacy
@Mock lateinit var profileFunction: ProfileFunction
@Mock lateinit var config: Config
@Mock lateinit var context: Context
lateinit var dateUtil: DateUtil
val rxBus = RxBus(aapsSchedulers, aapsLogger)
val profileInjector = HasAndroidInjector { AndroidInjector { } }
private lateinit var validProfileJSON: String
lateinit var validProfile: ProfileSealed.Pure
lateinit var effectiveProfileSwitch: EffectiveProfileSwitch
@Suppress("PropertyName") val TESTPROFILENAME = "someProfile"
@Before
fun prepareMock() {
validProfileJSON = "{\"dia\":\"5\",\"carbratio\":[{\"time\":\"00:00\",\"value\":\"30\"}],\"carbs_hr\":\"20\",\"delay\":\"20\",\"sens\":[{\"time\":\"00:00\",\"value\":\"3\"}," +
"{\"time\":\"2:00\",\"value\":\"3.4\"}],\"timezone\":\"UTC\",\"basal\":[{\"time\":\"00:00\",\"value\":\"1\"}],\"target_low\":[{\"time\":\"00:00\",\"value\":\"4.5\"}]," +
"\"target_high\":[{\"time\":\"00:00\",\"value\":\"7\"}],\"startDate\":\"1970-01-01T00:00:00.000Z\",\"units\":\"mmol\"}"
dateUtil = Mockito.spy(DateUtil(context))
`when`(dateUtil.now()).thenReturn(1656358822000)
validProfile = ProfileSealed.Pure(pureProfileFromJson(JSONObject(validProfileJSON), dateUtil)!!)
effectiveProfileSwitch = EffectiveProfileSwitch(
timestamp = dateUtil.now(),
basalBlocks = validProfile.basalBlocks,
isfBlocks = validProfile.isfBlocks,
icBlocks = validProfile.icBlocks,
targetBlocks = validProfile.targetBlocks,
glucoseUnit = EffectiveProfileSwitch.GlucoseUnit.MMOL,
originalProfileName = "",
originalCustomizedName = "",
originalTimeshift = 0,
originalPercentage = 100,
originalDuration = 0,
originalEnd = 0,
insulinConfiguration = InsulinConfiguration("", 0, 0)
)
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<Int?>(1)
String.format(rh.gs(string), arg1)
}.`when`(rh).gs(anyInt(), anyInt())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<Double?>(1)
String.format(rh.gs(string), arg1)
}.`when`(rh).gs(anyInt(), anyDouble())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<String?>(1)
String.format(rh.gs(string), arg1)
}.`when`(rh).gs(anyInt(), anyString())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<String?>(1)
val arg2 = invocation.getArgument<String?>(2)
String.format(rh.gs(string), arg1, arg2)
}.`when`(rh).gs(anyInt(), anyString(), anyString())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<String?>(1)
val arg2 = invocation.getArgument<Int?>(2)
String.format(rh.gs(string), arg1, arg2)
}.`when`(rh).gs(anyInt(), anyString(), anyInt())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<Double?>(1)
val arg2 = invocation.getArgument<String?>(2)
String.format(rh.gs(string), arg1, arg2)
}.`when`(rh).gs(anyInt(), anyDouble(), anyString())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<Double?>(1)
val arg2 = invocation.getArgument<Int?>(2)
String.format(rh.gs(string), arg1, arg2)
}.`when`(rh).gs(anyInt(), anyDouble(), anyInt())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<Int?>(1)
val arg2 = invocation.getArgument<Int?>(2)
String.format(rh.gs(string), arg1, arg2)
}.`when`(rh).gs(anyInt(), anyInt(), anyInt())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<Int?>(1)
val arg2 = invocation.getArgument<String?>(2)
String.format(rh.gs(string), arg1, arg2)
}.`when`(rh).gs(anyInt(), anyInt(), anyString())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<Int?>(1)
val arg2 = invocation.getArgument<Int?>(2)
val arg3 = invocation.getArgument<String?>(3)
String.format(rh.gs(string), arg1, arg2, arg3)
}.`when`(rh).gs(anyInt(), anyInt(), anyInt(), anyString())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<Int?>(1)
val arg2 = invocation.getArgument<String?>(2)
val arg3 = invocation.getArgument<String?>(3)
String.format(rh.gs(string), arg1, arg2, arg3)
}.`when`(rh).gs(anyInt(), anyInt(), anyString(), anyString())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<Double?>(1)
val arg2 = invocation.getArgument<Int?>(2)
val arg3 = invocation.getArgument<String?>(3)
String.format(rh.gs(string), arg1, arg2, arg3)
}.`when`(rh).gs(anyInt(), anyDouble(), anyInt(), anyString())
Mockito.doAnswer { invocation: InvocationOnMock ->
val string = invocation.getArgument<Int>(0)
val arg1 = invocation.getArgument<String?>(1)
val arg2 = invocation.getArgument<Int?>(2)
val arg3 = invocation.getArgument<String?>(3)
String.format(rh.gs(string), arg1, arg2, arg3)
}.`when`(rh).gs(anyInt(), anyString(), anyInt(), anyString())
}
fun getValidProfileStore(): ProfileStore {
val json = JSONObject()
val store = JSONObject()
store.put(TESTPROFILENAME, JSONObject(validProfileJSON))
json.put("defaultProfile", TESTPROFILENAME)
json.put("store", store)
return ProfileStore(profileInjector, json, dateUtil)
}
}

View file

@ -0,0 +1,68 @@
package info.nightscout.androidaps
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.DetailedBolusInfo
import info.nightscout.androidaps.interfaces.Profile
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.interfaces.PumpDescription
import info.nightscout.androidaps.interfaces.Pump
import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.plugins.common.ManufacturerType
import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.utils.TimeChangeType
import org.json.JSONObject
@Suppress("MemberVisibilityCanBePrivate")
class TestPumpPlugin(val injector: HasAndroidInjector) : Pump {
var connected = false
var isProfileSet = true
override fun isConnected() = connected
override fun isConnecting() = false
override fun isHandshakeInProgress() = false
val lastData = 0L
val baseBasal = 0.0
override val pumpDescription = PumpDescription()
override fun isInitialized(): Boolean = true
override fun isSuspended(): Boolean = false
override fun isBusy(): Boolean = false
override fun connect(reason: String) {
connected = true
}
override fun disconnect(reason: String) {
connected = false
}
override fun stopConnecting() {
connected = false
}
override fun waitForDisconnectionInSeconds(): Int = 0
override fun getPumpStatus(reason: String) {}
override fun setNewBasalProfile(profile: Profile): PumpEnactResult = PumpEnactResult(injector)
override fun isThisProfileSet(profile: Profile): Boolean = isProfileSet
override fun lastDataTime(): Long = lastData
override val baseBasalRate: Double = baseBasal
override val reservoirLevel: Double = 0.0
override val batteryLevel: Int = 0
override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun stopBolusDelivering() {}
override fun setTempBasalAbsolute(absoluteRate: Double, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun setTempBasalPercent(percent: Int, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun setExtendedBolus(insulin: Double, durationInMinutes: Int): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun cancelExtendedBolus(): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun getJSONStatus(profile: Profile, profileName: String, version: String): JSONObject = JSONObject()
override fun manufacturer(): ManufacturerType = ManufacturerType.AAPS
override fun model(): PumpType = PumpType.GENERIC_AAPS
override fun serialNumber(): String = "1"
override fun shortStatus(veryShort: Boolean): String = ""
override val isFakingTempsByExtendedBoluses: Boolean = false
override fun loadTDDs(): PumpEnactResult = PumpEnactResult(injector).success(true)
override fun canHandleDST(): Boolean = true
override fun timezoneOrDSTChanged(timeChangeType: TimeChangeType) {}
}

View file

@ -1,10 +1,10 @@
package info.nightscout.androidaps.queue package info.nightscout.implementation.queue
import android.content.Context import android.content.Context
import android.os.PowerManager import android.os.PowerManager
import dagger.android.AndroidInjector import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R import info.nightscout.implementation.R
import info.nightscout.androidaps.TestBaseWithProfile import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.androidaps.TestPumpPlugin import info.nightscout.androidaps.TestPumpPlugin
import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.DetailedBolusInfo
@ -13,30 +13,35 @@ import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.database.ValueWrapper import info.nightscout.androidaps.database.ValueWrapper
import info.nightscout.androidaps.database.entities.Bolus import info.nightscout.androidaps.database.entities.Bolus
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.AndroidPermission
import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.interfaces.Config import info.nightscout.androidaps.interfaces.Config
import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.interfaces.ProfileFunction import info.nightscout.androidaps.interfaces.ProfileFunction
import info.nightscout.androidaps.interfaces.PumpSync import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.shared.logging.AAPSLogger import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.queue.commands.* import info.nightscout.androidaps.queue.commands.*
import info.nightscout.androidaps.utils.AndroidPermission
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl
import info.nightscout.androidaps.interfaces.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.implementation.queue.commands.CommandBolus
import info.nightscout.implementation.queue.commands.CommandCustomCommand
import info.nightscout.implementation.queue.commands.CommandExtendedBolus
import info.nightscout.implementation.queue.commands.CommandLoadHistory
import info.nightscout.implementation.queue.commands.CommandTempBasalPercent
import info.nightscout.shared.logging.AAPSLogger
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import io.reactivex.rxjava3.core.Single import io.reactivex.rxjava3.core.Single
import org.junit.Assert import org.junit.Assert
import org.junit.Before import org.junit.Before
import org.junit.Test import org.junit.Test
import org.mockito.Mock import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.Mockito.anyLong import org.mockito.Mockito.anyLong
import org.mockito.Mockito.`when`
import java.util.* import java.util.*
class CommandQueueImplementationTest : TestBaseWithProfile() { class CommandQueueImplementationTest : TestBaseWithProfile() {
@ -47,6 +52,7 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
@Mock lateinit var powerManager: PowerManager @Mock lateinit var powerManager: PowerManager
@Mock lateinit var repository: AppRepository @Mock lateinit var repository: AppRepository
@Mock lateinit var fileListProvider: PrefFileListProvider @Mock lateinit var fileListProvider: PrefFileListProvider
@Mock lateinit var buildHelper: BuildHelper
@Mock lateinit var androidPermission: AndroidPermission @Mock lateinit var androidPermission: AndroidPermission
class CommandQueueMocked( class CommandQueueMocked(
@ -66,8 +72,10 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
fabricPrivacy: FabricPrivacy, fabricPrivacy: FabricPrivacy,
config: Config, config: Config,
androidPermission: AndroidPermission androidPermission: AndroidPermission
) : CommandQueueImplementation(injector, aapsLogger, rxBus, aapsSchedulers, rh, constraintChecker, profileFunction, ) : CommandQueueImplementation(
activePlugin, context, sp, buildHelper, dateUtil, repository, fabricPrivacy, config, androidPermission) { injector, aapsLogger, rxBus, aapsSchedulers, rh, constraintChecker, profileFunction,
activePlugin, context, sp, buildHelper, dateUtil, repository, fabricPrivacy, config, androidPermission
) {
override fun notifyAboutNewCommand() {} override fun notifyAboutNewCommand() {}
@ -106,11 +114,13 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
@Before @Before
fun prepare() { fun prepare() {
commandQueue = CommandQueueMocked(injector, aapsLogger, rxBus, aapsSchedulers, rh, commandQueue = CommandQueueMocked(
injector, aapsLogger, rxBus, aapsSchedulers, rh,
constraintChecker, profileFunction, activePlugin, context, sp, constraintChecker, profileFunction, activePlugin, context, sp,
BuildHelperImpl(config, fileListProvider), dateUtil, buildHelper, dateUtil,
repository, repository,
fabricPrivacy, config, androidPermission) fabricPrivacy, config, androidPermission
)
testPumpPlugin = TestPumpPlugin(injector) testPumpPlugin = TestPumpPlugin(injector)
testPumpPlugin.pumpDescription.basalMinimumRate = 0.1 testPumpPlugin.pumpDescription.basalMinimumRate = 0.1
@ -136,18 +146,20 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
`when`(constraintChecker.applyBasalConstraints(anyObject(), anyObject())).thenReturn(rateConstraint) `when`(constraintChecker.applyBasalConstraints(anyObject(), anyObject())).thenReturn(rateConstraint)
val percentageConstraint = Constraint(0) val percentageConstraint = Constraint(0)
`when`(constraintChecker.applyBasalPercentConstraints(anyObject(), anyObject())).thenReturn(percentageConstraint) `when`(constraintChecker.applyBasalPercentConstraints(anyObject(), anyObject())).thenReturn(percentageConstraint)
`when`(rh.gs(R.string.connectiontimedout)).thenReturn("Connection timed out") val thenReturn = `when`(rh.gs(R.string.connectiontimedout)).thenReturn("Connection timed out")
`when`(rh.gs(R.string.formatinsulinunits)).thenReturn("%1\$.2f U") `when`(rh.gs(R.string.formatinsulinunits)).thenReturn("%1\$.2f U")
`when`(rh.gs(R.string.bolusrequested)).thenReturn("Going to deliver %1\$.2f U") `when`(rh.gs(R.string.goingtodeliver)).thenReturn("Going to deliver %1\$.2f U")
} }
@Test @Test
fun commandIsPickedUp() { fun commandIsPickedUp() {
val commandQueue = CommandQueueImplementation(injector, aapsLogger, rxBus, aapsSchedulers, rh, val commandQueue = CommandQueueImplementation(
injector, aapsLogger, rxBus, aapsSchedulers, rh,
constraintChecker, profileFunction, activePlugin, context, sp, constraintChecker, profileFunction, activePlugin, context, sp,
BuildHelperImpl(config, fileListProvider), buildHelper,
dateUtil, repository, dateUtil, repository,
fabricPrivacy, config, androidPermission) fabricPrivacy, config, androidPermission
)
// start with empty queue // start with empty queue
Assert.assertEquals(0, commandQueue.size()) Assert.assertEquals(0, commandQueue.size())

View file

@ -1,23 +1,22 @@
package info.nightscout.androidaps.queue package info.nightscout.implementation.queue
import android.content.Context import android.content.Context
import android.os.PowerManager import android.os.PowerManager
import dagger.android.AndroidInjector import dagger.android.AndroidInjector
import dagger.android.HasAndroidInjector import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.R
import info.nightscout.androidaps.TestBaseWithProfile import info.nightscout.androidaps.TestBaseWithProfile
import info.nightscout.androidaps.TestPumpPlugin import info.nightscout.androidaps.TestPumpPlugin
import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.AppRepository
import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.ActivePlugin
import info.nightscout.androidaps.interfaces.AndroidPermission
import info.nightscout.androidaps.interfaces.BuildHelper
import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.Constraint
import info.nightscout.androidaps.interfaces.PumpDescription import info.nightscout.androidaps.interfaces.PumpDescription
import info.nightscout.androidaps.interfaces.PumpSync import info.nightscout.androidaps.interfaces.PumpSync
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.general.maintenance.PrefFileListProvider
import info.nightscout.androidaps.queue.commands.Command import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.androidaps.queue.commands.CommandTempBasalAbsolute import info.nightscout.implementation.R
import info.nightscout.androidaps.utils.AndroidPermission import info.nightscout.implementation.queue.commands.CommandTempBasalAbsolute
import info.nightscout.androidaps.utils.buildHelper.BuildHelperImpl
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import org.junit.Assert import org.junit.Assert
import org.junit.Before import org.junit.Before
@ -31,9 +30,9 @@ class QueueThreadTest : TestBaseWithProfile() {
@Mock lateinit var constraintChecker: ConstraintChecker @Mock lateinit var constraintChecker: ConstraintChecker
@Mock lateinit var activePlugin: ActivePlugin @Mock lateinit var activePlugin: ActivePlugin
@Mock lateinit var sp: SP @Mock lateinit var sp: SP
@Mock lateinit var fileListProvider: PrefFileListProvider
@Mock lateinit var powerManager: PowerManager @Mock lateinit var powerManager: PowerManager
@Mock lateinit var repository: AppRepository @Mock lateinit var repository: AppRepository
@Mock lateinit var buildHelper: BuildHelper
@Mock lateinit var androidPermission: AndroidPermission @Mock lateinit var androidPermission: AndroidPermission
val injector = HasAndroidInjector { val injector = HasAndroidInjector {
@ -59,7 +58,7 @@ class QueueThreadTest : TestBaseWithProfile() {
commandQueue = CommandQueueImplementation( commandQueue = CommandQueueImplementation(
injector, aapsLogger, rxBus, aapsSchedulers, rh, constraintChecker, injector, aapsLogger, rxBus, aapsSchedulers, rh, constraintChecker,
profileFunction, activePlugin, context, sp, profileFunction, activePlugin, context, sp,
BuildHelperImpl(config, fileListProvider), dateUtil, repository, fabricPrivacy, config, androidPermission buildHelper, dateUtil, repository, fabricPrivacy, config, androidPermission
) )
val pumpDescription = PumpDescription() val pumpDescription = PumpDescription()

View file

@ -31,6 +31,7 @@ import javax.inject.Singleton;
import dagger.android.HasAndroidInjector; import dagger.android.HasAndroidInjector;
import info.nightscout.androidaps.data.DetailedBolusInfo; import info.nightscout.androidaps.data.DetailedBolusInfo;
import info.nightscout.androidaps.interfaces.Insight;
import info.nightscout.androidaps.interfaces.Profile; import info.nightscout.androidaps.interfaces.Profile;
import info.nightscout.androidaps.data.PumpEnactResult; import info.nightscout.androidaps.data.PumpEnactResult;
import info.nightscout.androidaps.events.EventInitializationChanged; import info.nightscout.androidaps.events.EventInitializationChanged;
@ -134,7 +135,8 @@ import info.nightscout.androidaps.interfaces.ResourceHelper;
import info.nightscout.shared.sharedPreferences.SP; import info.nightscout.shared.sharedPreferences.SP;
@Singleton @Singleton
public class LocalInsightPlugin extends PumpPluginBase implements Pump, Constraints, InsightConnectionService.StateCallback { public class LocalInsightPlugin extends PumpPluginBase implements Pump, Insight, Constraints,
InsightConnectionService.StateCallback {
private final AAPSLogger aapsLogger; private final AAPSLogger aapsLogger;
private final RxBus rxBus; private final RxBus rxBus;