From 4628f3136deebb62cbd167618ebecac5657285b7 Mon Sep 17 00:00:00 2001 From: Andries Smit Date: Thu, 23 Jun 2022 20:31:40 +0200 Subject: [PATCH 01/63] feat: wear mulitple plus buttons --- .../androidaps/dialogs/CarbsDialog.kt | 6 +- .../androidaps/dialogs/InsulinDialog.kt | 6 +- .../wear/wearintegration/DataHandlerMobile.kt | 10 +- .../nightscout/shared/weardata/EventData.kt | 6 +- wear/build.gradle | 5 + .../androidaps/comm/DataHandlerWear.kt | 6 +- .../interaction/actions/BolusActivity.kt | 12 +- .../interaction/actions/CarbActivity.kt | 10 +- .../interaction/actions/ECarbActivity.kt | 10 +- .../interaction/actions/TreatmentActivity.kt | 18 +- .../actions/ViewSelectorActivity.kt | 13 +- .../interaction/actions/WizardActivity.kt | 11 +- .../utils/EditPlusMinusViewAdapter.kt | 78 ++++++++ .../interaction/utils/PlusMinusEditText.kt | 179 ++++++++++++------ .../res/layout/action_editplusminus_item.xml | 5 +- .../action_editplusminus_item_quicklefty.xml | 54 +++++- ...ion_editplusminus_item_quicklefty_plus.xml | 131 +++++++++++++ .../action_editplusminus_item_quickrighty.xml | 55 +++++- ...on_editplusminus_item_quickrighty_plus.xml | 131 +++++++++++++ .../action_editplusminus_item_viktoria.xml | 4 +- wear/src/main/res/values/strings.xml | 4 + 21 files changed, 645 insertions(+), 109 deletions(-) create mode 100644 wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt create mode 100644 wear/src/main/res/layout/action_editplusminus_item_quicklefty_plus.xml create mode 100644 wear/src/main/res/layout/action_editplusminus_item_quickrighty_plus.xml diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt index 7c73776689..ff3d0c778a 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt @@ -56,9 +56,9 @@ class CarbsDialog : DialogFragmentWithDate() { companion object { - private const val FAV1_DEFAULT = 5 - private const val FAV2_DEFAULT = 10 - private const val FAV3_DEFAULT = 20 + const val FAV1_DEFAULT = 5 + const val FAV2_DEFAULT = 10 + const val FAV3_DEFAULT = 20 } private var queryingProtection = false diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt index 9efb110a4f..7c45fe99ee 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/InsulinDialog.kt @@ -58,9 +58,9 @@ class InsulinDialog : DialogFragmentWithDate() { companion object { - private const val PLUS1_DEFAULT = 0.5 - private const val PLUS2_DEFAULT = 1.0 - private const val PLUS3_DEFAULT = 2.0 + const val PLUS1_DEFAULT = 0.5 + const val PLUS2_DEFAULT = 1.0 + const val PLUS3_DEFAULT = 2.0 } private var queryingProtection = false diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt index a0ccacf982..25017bfa3b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt @@ -12,6 +12,8 @@ import info.nightscout.androidaps.database.entities.* import info.nightscout.androidaps.database.interfaces.end import info.nightscout.androidaps.database.transactions.CancelCurrentTemporaryTargetIfAnyTransaction import info.nightscout.androidaps.database.transactions.InsertAndCancelCurrentTemporaryTargetTransaction +import info.nightscout.androidaps.dialogs.CarbsDialog +import info.nightscout.androidaps.dialogs.InsulinDialog import info.nightscout.androidaps.events.EventMobileToWear import info.nightscout.androidaps.extensions.convertedToAbsolute import info.nightscout.androidaps.extensions.toStringShort @@ -694,7 +696,11 @@ class DataHandlerMobile @Inject constructor( unitsMgdl = profileFunction.getUnits() == GlucoseUnit.MGDL, bolusPercentage = sp.getInt(R.string.key_boluswizard_percentage, 100), maxCarbs = sp.getInt(R.string.key_treatmentssafety_maxcarbs, 48), - maxBolus = sp.getDouble(R.string.key_treatmentssafety_maxbolus, 3.0) + maxBolus = sp.getDouble(R.string.key_treatmentssafety_maxbolus, 3.0), + insulin_button_increment_1 = sp.getDouble(R.string.key_insulin_button_increment_1, InsulinDialog.PLUS1_DEFAULT), + insulin_button_increment_2 = sp.getDouble(R.string.key_insulin_button_increment_2, InsulinDialog.PLUS2_DEFAULT), + carbs_button_increment_1 = sp.getInt(R.string.key_carbs_button_increment_1, CarbsDialog.FAV1_DEFAULT), + carbs_button_increment_2 = sp.getInt(R.string.key_carbs_button_increment_2, CarbsDialog.FAV2_DEFAULT) ) ) ) @@ -1185,4 +1191,4 @@ class DataHandlerMobile @Inject constructor( @Synchronized private fun sendError(errorMessage: String) { rxBus.send(EventMobileToWear(EventData.ConfirmAction(rh.gs(R.string.error), errorMessage, returnCommand = EventData.Error(dateUtil.now())))) // ignore return path } -} \ No newline at end of file +} diff --git a/shared/src/main/java/info/nightscout/shared/weardata/EventData.kt b/shared/src/main/java/info/nightscout/shared/weardata/EventData.kt index aca2303c89..bd0d06711b 100644 --- a/shared/src/main/java/info/nightscout/shared/weardata/EventData.kt +++ b/shared/src/main/java/info/nightscout/shared/weardata/EventData.kt @@ -208,7 +208,11 @@ sealed class EventData : Event() { val unitsMgdl: Boolean, val bolusPercentage: Int, val maxCarbs: Int, - val maxBolus: Double + val maxBolus: Double, + val insulin_button_increment_1: Double, + val insulin_button_increment_2: Double, + val carbs_button_increment_1: Int, + val carbs_button_increment_2: Int ) : EventData() @Serializable diff --git a/wear/build.gradle b/wear/build.gradle index ddcfcbfa2f..802c30ddef 100644 --- a/wear/build.gradle +++ b/wear/build.gradle @@ -53,6 +53,10 @@ android { buildConfigField "String", "BUILDVERSION", generateGitBuild() } + buildFeatures { + viewBinding true + } + flavorDimensions "standard" productFlavors { full { @@ -98,6 +102,7 @@ dependencies { implementation "androidx.preference:preference-ktx:$preferencektx_version" implementation 'androidx.wear:wear:1.2.0' implementation "androidx.wear.tiles:tiles:1.0.1" + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' compileOnly "com.google.android.wearable:wearable:$wearable_version" implementation "com.google.android.support:wearable:$wearable_version" diff --git a/wear/src/main/java/info/nightscout/androidaps/comm/DataHandlerWear.kt b/wear/src/main/java/info/nightscout/androidaps/comm/DataHandlerWear.kt index cac52e5439..3a05c06cf0 100644 --- a/wear/src/main/java/info/nightscout/androidaps/comm/DataHandlerWear.kt +++ b/wear/src/main/java/info/nightscout/androidaps/comm/DataHandlerWear.kt @@ -162,6 +162,10 @@ class DataHandlerWear @Inject constructor( sp.putInt(R.string.key_bolus_wizard_percentage, it.bolusPercentage) sp.putInt(R.string.key_treatments_safety_max_carbs, it.maxCarbs) sp.putDouble(R.string.key_treatments_safety_max_bolus, it.maxBolus) + sp.putDouble(R.string.key_insulin_button_increment_1, it.insulin_button_increment_1) + sp.putDouble(R.string.key_insulin_button_increment_2, it.insulin_button_increment_2) + sp.putInt(R.string.key_carbs_button_increment_1, it.carbs_button_increment_1) + sp.putInt(R.string.key_carbs_button_increment_2, it.carbs_button_increment_2) } disposable += rxBus .toObservable(EventData.QuickWizard::class.java) @@ -284,4 +288,4 @@ class DataHandlerWear @Inject constructor( NotificationManagerCompat.from(context).cancel(DataLayerListenerServiceWear.BOLUS_PROGRESS_NOTIF_ID) }.start() } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/BolusActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/BolusActivity.kt index e7e8b56355..766983c581 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/BolusActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/BolusActivity.kt @@ -10,10 +10,12 @@ import android.view.ViewGroup import android.widget.ImageView import info.nightscout.androidaps.R import info.nightscout.androidaps.events.EventWearToMobile +import info.nightscout.androidaps.interaction.utils.EditPlusMinusViewAdapter import info.nightscout.androidaps.interaction.utils.PlusMinusEditText import info.nightscout.shared.SafeParse import info.nightscout.shared.weardata.EventData.ActionBolusPreCheck import java.text.DecimalFormat +import kotlin.math.roundToInt class BolusActivity : ViewSelectorActivity() { @@ -33,13 +35,17 @@ class BolusActivity : ViewSelectorActivity() { override fun getColumnCount(arg0: Int): Int = 2 override fun getRowCount(): Int = 1 + val increment1 = (sp.getDouble(R.string.key_insulin_button_increment_1, 0.5) * 10).roundToInt() / 10.0 + val increment2 = (sp.getDouble(R.string.key_insulin_button_increment_2, 1.0) * 10).roundToInt() / 10.0 + override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { val view: View if (col == 0) { - view = getInflatedPlusMinusView(container) + view = EditPlusMinusViewAdapter.getInflatedPlusMinusView(sp, applicationContext, container, true).root val initValue = if (editInsulin != null) SafeParse.stringToDouble(editInsulin?.editText?.text.toString()) else 0.0 val maxBolus = sp.getDouble(getString(R.string.key_treatments_safety_max_bolus), 3.0) - editInsulin = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, initValue, 0.0, maxBolus, 0.1, DecimalFormat("#0.0"), false) + val buttons = listOf(Pair(R.id.plusbutton, 0.1), Pair(R.id.plusbutton2, increment1), Pair(R.id.plusbutton3, increment2)) // When taken form phone settings round. + editInsulin = PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, initValue, 0.0, maxBolus, 0.1, DecimalFormat("#0.0"), false) setLabelToPlusMinusView(view, getString(R.string.action_insulin)) container.addView(view) view.requestFocus() @@ -62,4 +68,4 @@ class BolusActivity : ViewSelectorActivity() { override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object` } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/CarbActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/CarbActivity.kt index 4dd487bb79..7de9a45dd3 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/CarbActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/CarbActivity.kt @@ -30,19 +30,23 @@ class CarbActivity : ViewSelectorActivity() { private inner class MyGridViewPagerAdapter : GridPagerAdapter() { + val increment1 = sp.getInt(R.string.key_carbs_button_increment_1, 5).toDouble() + val increment2 = sp.getInt(R.string.key_carbs_button_increment_2, 10).toDouble() + override fun getColumnCount(arg0: Int): Int = 2 override fun getRowCount(): Int = 1 override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { val view: View if (col == 0) { - view = getInflatedPlusMinusView(container) + view = getInflatedPlusMinusView(container, true) var def = 0.0 if (editCarbs != null) { def = SafeParse.stringToDouble(editCarbs?.editText?.text.toString()) } val maxCarbs = sp.getInt(getString(R.string.key_treatments_safety_max_carbs), 48) - editCarbs = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), true) + val buttons = listOf(Pair(R.id.plusbutton, 1.0), Pair(R.id.plusbutton2, increment1), Pair(R.id.plusbutton3, increment2)) + editCarbs = PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), true) setLabelToPlusMinusView(view, getString(R.string.action_carbs)) container.addView(view) view.requestFocus() @@ -69,4 +73,4 @@ class CarbActivity : ViewSelectorActivity() { override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object` } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ECarbActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ECarbActivity.kt index 21d7b41f31..50988562a4 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ECarbActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ECarbActivity.kt @@ -36,15 +36,19 @@ class ECarbActivity : ViewSelectorActivity() { override fun getColumnCount(arg0: Int): Int = 4 override fun getRowCount(): Int = 1 + private val increment1 = sp.getInt(R.string.key_carbs_button_increment_1, 5).toDouble() + private val increment2 = sp.getInt(R.string.key_carbs_button_increment_2, 10).toDouble() + override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { return if (col == 0) { - val view = getInflatedPlusMinusView(container) + val view = getInflatedPlusMinusView(container, true) var def = 0.0 if (editCarbs != null) { def = stringToDouble(editCarbs?.editText?.text.toString()) } val maxCarbs = sp.getInt(getString(R.string.key_treatments_safety_max_carbs), 48) - editCarbs = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), true) + val buttons = listOf(Pair(R.id.plusbutton, 1.0), Pair(R.id.plusbutton2, increment1), Pair(R.id.plusbutton3, increment2)) + editCarbs = PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), true) setLabelToPlusMinusView(view, getString(R.string.action_carbs)) container.addView(view) view.requestFocus() @@ -98,4 +102,4 @@ class ECarbActivity : ViewSelectorActivity() { override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object` } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TreatmentActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TreatmentActivity.kt index ed504969b1..630317b89a 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TreatmentActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TreatmentActivity.kt @@ -15,6 +15,7 @@ import info.nightscout.shared.SafeParse.stringToDouble import info.nightscout.shared.SafeParse.stringToInt import info.nightscout.shared.weardata.EventData.ActionBolusPreCheck import java.text.DecimalFormat +import kotlin.math.roundToInt class TreatmentActivity : ViewSelectorActivity() { @@ -35,23 +36,30 @@ class TreatmentActivity : ViewSelectorActivity() { override fun getColumnCount(arg0: Int): Int = 3 override fun getRowCount(): Int = 1 + val incrementInsulin1 = (sp.getDouble(R.string.key_insulin_button_increment_1, 0.5) * 10).roundToInt() / 10.0 + val incrementInsulin2 = (sp.getDouble(R.string.key_insulin_button_increment_2, 1.0) * 10).roundToInt() / 10.0 + val incrementCarbs1 = sp.getInt(R.string.key_carbs_button_increment_1, 5).toDouble() + val incrementCarbs2 = sp.getInt(R.string.key_carbs_button_increment_2, 10).toDouble() + override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { return if (col == 0) { - val view = getInflatedPlusMinusView(container) + val view = getInflatedPlusMinusView(container, true) var def = 0.0 if (editInsulin != null) def = stringToDouble(editInsulin?.editText?.text.toString()) val maxBolus = sp.getDouble(getString(R.string.key_treatments_safety_max_bolus), 3.0) - editInsulin = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 0.0, maxBolus, 0.1, DecimalFormat("#0.0"), false) + val buttons = listOf(Pair(R.id.plusbutton, 0.1), Pair(R.id.plusbutton2, incrementInsulin1), Pair(R.id.plusbutton3, incrementInsulin2)) + editInsulin = PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, def, 0.0, maxBolus, 0.1, DecimalFormat("#0.0"), false) setLabelToPlusMinusView(view, getString(R.string.action_insulin)) container.addView(view) view.requestFocus() view } else if (col == 1) { - val view = getInflatedPlusMinusView(container) + val view = getInflatedPlusMinusView(container, true) var def = 0.0 val maxCarbs = sp.getInt(getString(R.string.key_treatments_safety_max_carbs), 48) if (editCarbs != null) def = stringToDouble(editCarbs?.editText?.text.toString()) - editCarbs = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false) + val buttons = listOf(Pair(R.id.plusbutton, 1.0), Pair(R.id.plusbutton2, incrementCarbs1), Pair(R.id.plusbutton3, incrementCarbs2)) + editCarbs = PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false) setLabelToPlusMinusView(view, getString(R.string.action_carbs)) container.addView(view) view @@ -79,4 +87,4 @@ class TreatmentActivity : ViewSelectorActivity() { override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object` } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ViewSelectorActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ViewSelectorActivity.kt index 9fd6b9adf1..eb3a9b70d7 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ViewSelectorActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ViewSelectorActivity.kt @@ -73,13 +73,16 @@ open class ViewSelectorActivity : DaggerActivity() { } } - fun getInflatedPlusMinusView(container: ViewGroup?): View = - when (sp.getInt(R.string.key_input_design, 1)) { - 2 -> LayoutInflater.from(applicationContext).inflate(R.layout.action_editplusminus_item_quickrighty, container, false) - 3 -> LayoutInflater.from(applicationContext).inflate(R.layout.action_editplusminus_item_quicklefty, container, false) + fun getInflatedPlusMinusView(container: ViewGroup?, mulitple: Boolean = false): View { + val layoutRight = if (mulitple) R.layout.action_editplusminus_item_quickrighty_plus else R.layout.action_editplusminus_item_quickrighty + val layoutLeft = if (mulitple) R.layout.action_editplusminus_item_quicklefty_plus else R.layout.action_editplusminus_item_quicklefty + return when (sp.getInt(R.string.key_input_design, 1)) { + 2 -> LayoutInflater.from(applicationContext).inflate(layoutRight, container, false) + 3 -> LayoutInflater.from(applicationContext).inflate(layoutLeft, container, false) 4 -> LayoutInflater.from(applicationContext).inflate(R.layout.action_editplusminus_item_viktoria, container, false) else -> LayoutInflater.from(applicationContext).inflate(R.layout.action_editplusminus_item, container, false) } + } fun setLabelToPlusMinusView(view: View, labelText: String?) { val textView = view.findViewById(R.id.label) @@ -89,4 +92,4 @@ open class ViewSelectorActivity : DaggerActivity() { fun showToast(context: Context?, text: Int) { Toast.makeText(context, getString(text), Toast.LENGTH_LONG).show() } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/WizardActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/WizardActivity.kt index f8c6208e52..dfd6e6291b 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/WizardActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/WizardActivity.kt @@ -35,16 +35,19 @@ class WizardActivity : ViewSelectorActivity() { override fun getColumnCount(arg0: Int): Int = if (hasPercentage) 3 else 2 override fun getRowCount(): Int = 1 + private val increment1 = sp.getInt(R.string.key_carbs_button_increment_1, 5).toDouble() + private val increment2 = sp.getInt(R.string.key_carbs_button_increment_2, 10).toDouble() override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { return if (col == 0) { - val view = getInflatedPlusMinusView(container) + val view = getInflatedPlusMinusView(container, true) val maxCarbs = sp.getInt(getString(R.string.key_treatments_safety_max_carbs), 48) + val buttons = listOf(Pair(R.id.plusbutton, 1.0), Pair(R.id.plusbutton2, increment1), Pair(R.id.plusbutton3, increment2)) editCarbs = if (editCarbs == null) { - PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, 0.0, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false) + PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, 0.0, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false) } else { val def = SafeParse.stringToDouble(editCarbs?.editText?.text.toString()) - PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false) + PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false) } setLabelToPlusMinusView(view, getString(R.string.action_carbs)) container.addView(view) @@ -84,4 +87,4 @@ class WizardActivity : ViewSelectorActivity() { override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object` } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt new file mode 100644 index 0000000000..4b3798940b --- /dev/null +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt @@ -0,0 +1,78 @@ +package info.nightscout.androidaps.interaction.utils + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import info.nightscout.androidaps.R +import info.nightscout.androidaps.databinding.ActionEditplusminusItemBinding +import info.nightscout.androidaps.databinding.ActionEditplusminusItemQuickleftyPlusBinding +import info.nightscout.androidaps.databinding.ActionEditplusminusItemQuickleftyBinding +import info.nightscout.androidaps.databinding.ActionEditplusminusItemQuickrightyBinding +import info.nightscout.androidaps.databinding.ActionEditplusminusItemQuickrightyPlusBinding +import info.nightscout.androidaps.databinding.ActionEditplusminusItemViktoriaBinding +import info.nightscout.shared.sharedPreferences.SP + +/** + * NumberPickerViewAdapter binds both NumberPickerLayoutBinding and NumberPickerLayoutVerticalBinding shared attributes to one common view adapter. + * Requires at least one of the ViewBinding as a parameter. Recommended to use the factory object to create the binding. + */ +class EditPlusMinusViewAdapter( + val eS: ActionEditplusminusItemBinding?, + val eQLP: ActionEditplusminusItemQuickleftyPlusBinding?, + val eQL: ActionEditplusminusItemQuickleftyBinding?, + val eQRP: ActionEditplusminusItemQuickleftyPlusBinding?, + val qQR: ActionEditplusminusItemQuickrightyBinding?, + val nQRP: ActionEditplusminusItemQuickrightyPlusBinding?, + val eV: ActionEditplusminusItemViktoriaBinding? +) { + + init { + if (eS == null && eQLP == null && eQL == null && eQRP == null && qQR == null && nQRP == null && eV == null) { + throw IllegalArgumentException("Require at least on Binding parameter") + } + } + + val amountField = + eS?.amountfield ?: eQLP?.amountfield ?: eQL?.amountfield ?: eQRP?.amountfield ?: qQR?.amountfield ?: nQRP?.amountfield ?: eV?.amountfield + ?: throw IllegalArgumentException("Missing require View Binding parameter display") + val minusButton = + eS?.minusbutton ?: eQLP?.minusbutton ?: eQL?.minusbutton ?: eQRP?.minusbutton ?: qQR?.minusbutton ?: nQRP?.minusbutton ?: eV?.minusbutton + ?: throw IllegalArgumentException("Missing require View Binding parameter display") + val plusButton = + eS?.plusbutton ?: eQLP?.plusbutton ?: eQL?.plusbutton ?: eQRP?.plusbutton ?: qQR?.plusbutton ?: nQRP?.plusbutton ?: eV?.plusbutton + ?: throw IllegalArgumentException("Missing require View Binding parameter display") + val label = + eS?.label ?: eQLP?.label ?: eQL?.label ?: eQRP?.label ?: qQR?.label ?: nQRP?.label ?: eV?.label + ?: throw IllegalArgumentException("Missing require View Binding parameter display") + val plusButton2 = eQLP?.plusbutton2 ?: eQRP?.plusbutton2 + val plusButton3 = eQLP?.plusbutton3 ?: eQRP?.plusbutton3 + val root = + eS?.root ?: eQLP?.root ?: eQL?.root ?: eQRP?.root ?: qQR?.root ?: nQRP?.root ?: eV?.root + ?: throw IllegalArgumentException("Missing require View Binding parameter display") + + companion object { + + fun getInflatedPlusMinusView(sp: SP, context: Context, container: ViewGroup?, mulitple: Boolean = false): EditPlusMinusViewAdapter { + val inflater = LayoutInflater.from(context) + val bindLayout = ActionEditplusminusItemBinding.inflate(inflater, container, false) + val binding = EditPlusMinusViewAdapter(bindLayout, null, null, null, null, null, null) + return binding + // val layoutRight = if (mulitple) R.layout.action_editplusminus_item_quickrighty_plus else R.layout.action_editplusminus_item_quickrighty + // val layoutLeft = if (mulitple) R.layout.action_editplusminus_item_quicklefty_plus else R.layout.action_editplusminus_item_quicklefty + // return when (sp.getInt(R.string.key_input_design, 1)) { + // 2 -> LayoutInflater.from(applicationContext).inflate(layoutRight, container, false) + // 3 -> LayoutInflater.from(applicationContext).inflate(layoutLeft, container, false) + // 4 -> LayoutInflater.from(applicationContext).inflate(R.layout.action_editplusminus_item_viktoria, container, false) + // else -> LayoutInflater.from(applicationContext).inflate(R.layout.action_editplusminus_item, container, false) + // } + } + // fun getBinding(bindLayout: NumberPickerLayoutBinding): NumberPickerViewAdapter { + // return NumberPickerViewAdapter(bindLayout, null) + // } + // + // fun getBinding(bindLayout: NumberPickerLayoutVerticalBinding): NumberPickerViewAdapter { + // return NumberPickerViewAdapter(null, bindLayout) + // } + } +} \ No newline at end of file diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt index 1ee994c9d3..f812b7e245 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt @@ -1,67 +1,82 @@ package info.nightscout.androidaps.interaction.utils -import android.os.Handler -import kotlin.jvm.JvmOverloads -import android.view.View.OnTouchListener -import android.view.View.OnGenericMotionListener -import android.widget.TextView -import android.view.MotionEvent -import android.os.Looper -import android.os.Message +import android.annotation.SuppressLint +import android.content.Context +import android.os.* import android.view.KeyEvent +import android.view.MotionEvent import android.view.View -import android.widget.ImageView +import android.view.View.OnGenericMotionListener +import android.view.View.OnTouchListener +import android.widget.TextView +import androidx.appcompat.widget.AppCompatButton import androidx.core.view.InputDeviceCompat import androidx.core.view.MotionEventCompat +import java.text.DecimalFormat import java.text.NumberFormat import java.util.concurrent.Executors import java.util.concurrent.ScheduledExecutorService import java.util.concurrent.TimeUnit +import kotlin.Pair /** * Created by mike on 28.06.2016. */ -class PlusMinusEditText @JvmOverloads constructor( +@SuppressLint("SetTextI18n") class PlusMinusEditText @JvmOverloads constructor( view: View, editTextID: Int, - plusID: Int, + private var plusButtons: List>, minusID: Int, initValue: Double, - minValue: Double, - maxValue: Double, - step: Double, - formatter: NumberFormat, - allowZero: Boolean, - roundRobin: Boolean = false + private val minValue: Double, + private val maxValue: Double, + private val stepGeneral: Double, + private val formatter: NumberFormat, + private val allowZero: Boolean, + private val roundRobin: Boolean = false, ) : View.OnKeyListener, OnTouchListener, View.OnClickListener, OnGenericMotionListener { + constructor( + view: View, + editTextID: Int, + plusID: Int, + minusID: Int, + initValue: Double, + minValue: Double, + maxValue: Double, + stepGeneral: Double, + formatter: NumberFormat, + allowZero: Boolean, + roundRobin: Boolean = false + ) : this(view, editTextID, listOf(Pair(plusID, stepGeneral)), minusID, initValue, minValue, maxValue, stepGeneral, formatter, allowZero, roundRobin) + var editText: TextView private set - private var minusImage: ImageView - private var plusImage: ImageView + private var minusImage: View + private var plusImage1: View + private var plusImage2: AppCompatButton? = null + private var plusImage3: AppCompatButton? = null private var value: Double - private var minValue: Double - private var maxValue: Double - private var step: Double - private var formatter: NumberFormat - private var allowZero: Boolean - private var roundRobin: Boolean + private val context: Context private var mChangeCounter = 0 private var mLastChange: Long = 0 private val mHandler: Handler private var mUpdater: ScheduledExecutorService? = null - private inner class UpdateCounterTask(private val mInc: Boolean) : Runnable { + private inner class UpdateCounterTask(private val mInc: Boolean, private val step: Double) : Runnable { private var repeated = 0 private var multiplier = 1 override fun run() { val msg = Message() val doubleLimit = 5 - if (repeated % doubleLimit == 0) multiplier *= 2 - repeated++ - msg.arg1 = multiplier - msg.arg2 = repeated + val multipleButtons = mInc && (plusImage2 != null || plusImage3 != null) + if (!multipleButtons && repeated % doubleLimit == 0) multiplier *= 2 + val bundle = Bundle() + bundle.putDouble("step", step) + bundle.putInt("multiplier", multiplier) + msg.data = bundle + if (mInc) { msg.what = MSG_INC } else { @@ -71,7 +86,7 @@ class PlusMinusEditText @JvmOverloads constructor( } } - private fun inc(multiplier: Int) { + private fun inc(multiplier: Int, step: Double, vibrate: Boolean = true) { value += step * multiplier if (value > maxValue) { if (roundRobin) { @@ -82,9 +97,10 @@ class PlusMinusEditText @JvmOverloads constructor( } } updateEditText() + if (vibrate) vibrateDevice() } - private fun dec(multiplier: Int) { + private fun dec(multiplier: Int, step: Double, vibrate: Boolean = true) { value -= step * multiplier if (value < minValue) { if (roundRobin) { @@ -95,20 +111,39 @@ class PlusMinusEditText @JvmOverloads constructor( } } updateEditText() + if (vibrate) vibrateDevice() + } + + fun vibrateDevice() { + val vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + val vibratorManager = + context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager + vibratorManager.defaultVibrator + } else { + @Suppress("DEPRECATION") + context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + vibrator.vibrate(VibrationEffect.createOneShot(10, VibrationEffect.DEFAULT_AMPLITUDE)) + } else { + @Suppress("DEPRECATION") + vibrator.vibrate(10) + } } private fun updateEditText() { if (value == 0.0 && !allowZero) editText.text = "" else editText.text = formatter.format(value) } - private fun startUpdating(inc: Boolean) { + private fun startUpdating(inc: Boolean, step: Double) { if (mUpdater != null) { return } mUpdater = Executors.newSingleThreadScheduledExecutor() mUpdater?.scheduleAtFixedRate( - UpdateCounterTask(inc), 200, 200, + UpdateCounterTask(inc, step), 200, 200, TimeUnit.MILLISECONDS ) } @@ -118,12 +153,30 @@ class PlusMinusEditText @JvmOverloads constructor( mUpdater = null } + private fun getStep(v: View): Double { + return when (v) { + plusImage1 -> plusButtons[0].second + plusImage2 -> plusButtons[1].second + plusImage3 -> plusButtons[2].second + else -> stepGeneral + } + } + + private fun isIncrement(v: View): Boolean { + return when (v) { + plusImage1 -> true + plusImage2 -> true + plusImage3 -> true + else -> false + } + } + override fun onClick(v: View) { if (mUpdater == null) { - if (v === plusImage) { - inc(1) + if (isIncrement(v)) { + inc(1, getStep(v)) } else { - dec(1) + dec(1, getStep(v)) } } } @@ -135,7 +188,7 @@ class PlusMinusEditText @JvmOverloads constructor( if (isKeyOfInterest && isReleased) { stopUpdating() } else if (isKeyOfInterest && isPressed) { - startUpdating(v === plusImage) + startUpdating(isIncrement(v), stepGeneral) } return false } @@ -146,7 +199,7 @@ class PlusMinusEditText @JvmOverloads constructor( if (isReleased) { stopUpdating() } else if (isPressed) { - startUpdating(v === plusImage) + startUpdating(isIncrement(v), getStep(v)) } return false } @@ -158,9 +211,9 @@ class PlusMinusEditText @JvmOverloads constructor( val dynamicMultiplier = if (mChangeCounter < THRESHOLD_COUNTER) 1 else if (mChangeCounter < THRESHOLD_COUNTER_LONG) 2 else 4 val delta = -ev.getAxisValue(MotionEventCompat.AXIS_SCROLL) if (delta > 0) { - inc(dynamicMultiplier) + inc(dynamicMultiplier, stepGeneral, false) } else { - dec(dynamicMultiplier) + dec(dynamicMultiplier, stepGeneral, false) } mLastChange = System.currentTimeMillis() mChangeCounter++ @@ -179,39 +232,59 @@ class PlusMinusEditText @JvmOverloads constructor( } init { + context = view.context editText = view.findViewById(editTextID) minusImage = view.findViewById(minusID) - plusImage = view.findViewById(plusID) + plusImage1 = view.findViewById(plusButtons.first().first) + val format = DecimalFormat("#.#") + plusButtons.getOrNull(1)?.let { + plusImage2 = view.findViewById(it.first) + plusImage2?.text = "+${format.format(it.second).replaceFirst("^0+(?!$)".toRegex(), "")}" + plusImage2?.visibility = View.VISIBLE + } + plusButtons.getOrNull(2)?.let { + plusImage3 = view.findViewById(it.first) + plusImage3?.text = "+${format.format(it.second).replaceFirst("^0+(?!$)".toRegex(), "")}" + plusImage3?.visibility = View.VISIBLE + } + value = initValue - this.minValue = minValue - this.maxValue = maxValue - this.step = step - this.formatter = formatter - this.allowZero = allowZero - this.roundRobin = roundRobin mHandler = object : Handler(Looper.getMainLooper()) { override fun handleMessage(msg: Message) { + val multiplier = msg.data.getInt("multiplier") + val step = msg.data.getDouble("step") + when (msg.what) { MSG_INC -> { - inc(msg.arg1) + inc(multiplier, step) return } MSG_DEC -> { - dec(msg.arg1) + dec(multiplier, step) return } } super.handleMessage(msg) } } + + editText.showSoftInputOnFocus = false + editText.setTextIsSelectable(false) minusImage.setOnTouchListener(this) minusImage.setOnKeyListener(this) minusImage.setOnClickListener(this) - plusImage.setOnTouchListener(this) - plusImage.setOnKeyListener(this) - plusImage.setOnClickListener(this) + plusImage1.setOnTouchListener(this) + plusImage1.setOnKeyListener(this) + plusImage1.setOnClickListener(this) + plusImage2?.setOnTouchListener(this) + plusImage2?.setOnKeyListener(this) + plusImage2?.setOnClickListener(this) + plusImage3?.setOnTouchListener(this) + plusImage3?.setOnKeyListener(this) + plusImage3?.setOnClickListener(this) editText.setOnGenericMotionListener(this) updateEditText() } + } diff --git a/wear/src/main/res/layout/action_editplusminus_item.xml b/wear/src/main/res/layout/action_editplusminus_item.xml index c3cbe263ba..5c5b8856d5 100644 --- a/wear/src/main/res/layout/action_editplusminus_item.xml +++ b/wear/src/main/res/layout/action_editplusminus_item.xml @@ -7,7 +7,7 @@ android:gravity="center" android:orientation="horizontal"> - - - diff --git a/wear/src/main/res/layout/action_editplusminus_item_quicklefty.xml b/wear/src/main/res/layout/action_editplusminus_item_quicklefty.xml index bf3418ca2c..d96ae1d26f 100644 --- a/wear/src/main/res/layout/action_editplusminus_item_quicklefty.xml +++ b/wear/src/main/res/layout/action_editplusminus_item_quicklefty.xml @@ -7,16 +7,52 @@ android:gravity="center" android:orientation="horizontal"> - + android:layout_marginEnd="-8dp" + android:orientation="vertical"> + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + diff --git a/wear/src/main/res/layout/action_editplusminus_item_quickrighty.xml b/wear/src/main/res/layout/action_editplusminus_item_quickrighty.xml index 78c5d7e817..7e3ae3dcb1 100644 --- a/wear/src/main/res/layout/action_editplusminus_item_quickrighty.xml +++ b/wear/src/main/res/layout/action_editplusminus_item_quickrighty.xml @@ -41,7 +41,7 @@ tools:ignore="LabelFor" tools:text="label" /> - - + android:layout_marginStart="-8dp" + android:orientation="vertical" + tools:visibility="visible"> + + + + + + + + diff --git a/wear/src/main/res/layout/action_editplusminus_item_quickrighty_plus.xml b/wear/src/main/res/layout/action_editplusminus_item_quickrighty_plus.xml new file mode 100644 index 0000000000..07a9101a0e --- /dev/null +++ b/wear/src/main/res/layout/action_editplusminus_item_quickrighty_plus.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/wear/src/main/res/layout/action_editplusminus_item_viktoria.xml b/wear/src/main/res/layout/action_editplusminus_item_viktoria.xml index 0b396d8b7f..b734b9db7b 100644 --- a/wear/src/main/res/layout/action_editplusminus_item_viktoria.xml +++ b/wear/src/main/res/layout/action_editplusminus_item_viktoria.xml @@ -25,7 +25,7 @@ android:layout_gravity="start|center_vertical|center_horizontal" android:orientation="vertical"> - - dark input_design complication_tap_action + insulin_button_increment_1 + insulin_button_increment_2 + carbs_button_increment_1 + carbs_button_increment_2 increment decrement H From 14d1ba80abd325b7fc2787eaa41c9021da72776b Mon Sep 17 00:00:00 2001 From: Andries Smit Date: Sun, 26 Jun 2022 13:17:16 +0200 Subject: [PATCH 02/63] chore: wear: plus minus view adapter --- .../interaction/actions/AcceptActivity.kt | 18 +- .../interaction/actions/BolusActivity.kt | 23 +-- .../interaction/actions/CarbActivity.kt | 23 +-- .../interaction/actions/ECarbActivity.kt | 43 +++-- .../interaction/actions/FillActivity.kt | 17 +- .../actions/ProfileSwitchActivity.kt | 26 +-- .../interaction/actions/TempTargetActivity.kt | 46 +++--- .../interaction/actions/TreatmentActivity.kt | 30 ++-- .../actions/ViewSelectorActivity.kt | 16 -- .../interaction/actions/WizardActivity.kt | 31 ++-- .../utils/EditPlusMinusViewAdapter.kt | 97 ++++++----- .../interaction/utils/PlusMinusEditText.kt | 102 +++++------- .../res/layout/action_editplusminus_item.xml | 156 ++++++++++++------ .../layout/action_editplusminus_item_plus.xml | 126 ++++++++++++++ .../action_editplusminus_item_quicklefty.xml | 37 +---- ...ion_editplusminus_item_quicklefty_plus.xml | 54 +++--- .../action_editplusminus_item_quickrighty.xml | 35 +--- ...on_editplusminus_item_quickrighty_plus.xml | 42 +++-- .../action_editplusminus_item_viktoria.xml | 8 +- 19 files changed, 544 insertions(+), 386 deletions(-) create mode 100644 wear/src/main/res/layout/action_editplusminus_item_plus.xml diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/AcceptActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/AcceptActivity.kt index 2134f60f6d..b3c395fb76 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/AcceptActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/AcceptActivity.kt @@ -56,10 +56,9 @@ class AcceptActivity : ViewSelectorActivity() { override fun getColumnCount(arg0: Int): Int = 2 override fun getRowCount(): Int = 1 - override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { - val view: View - if (col == 0) { - view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_text, container, false) + override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when (col) { + 0 -> { + val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_text, container, false) val textView = view.findViewById(R.id.message) val scrollView = view.findViewById(R.id.message_scroll) textView.text = message @@ -79,8 +78,11 @@ class AcceptActivity : ViewSelectorActivity() { false } scrollView.requestFocus() - } else { - view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) + view + } + + else -> { + val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) val confirmButton = view.findViewById(R.id.confirmbutton) confirmButton.setOnClickListener { if (actionKey.isNotEmpty()) startService(IntentWearToMobile(this@AcceptActivity, actionKey)) @@ -88,8 +90,8 @@ class AcceptActivity : ViewSelectorActivity() { finishAffinity() } container.addView(view) + view } - return view } override fun destroyItem(container: ViewGroup, row: Int, col: Int, view: Any) { @@ -127,4 +129,4 @@ class AcceptActivity : ViewSelectorActivity() { finish() } } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/BolusActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/BolusActivity.kt index 766983c581..012d5ec516 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/BolusActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/BolusActivity.kt @@ -37,20 +37,23 @@ class BolusActivity : ViewSelectorActivity() { val increment1 = (sp.getDouble(R.string.key_insulin_button_increment_1, 0.5) * 10).roundToInt() / 10.0 val increment2 = (sp.getDouble(R.string.key_insulin_button_increment_2, 1.0) * 10).roundToInt() / 10.0 + val stepValues = listOf(0.1, increment1, increment2) - override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { - val view: View - if (col == 0) { - view = EditPlusMinusViewAdapter.getInflatedPlusMinusView(sp, applicationContext, container, true).root + override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when (col) { + 0 -> { + val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, true) val initValue = if (editInsulin != null) SafeParse.stringToDouble(editInsulin?.editText?.text.toString()) else 0.0 val maxBolus = sp.getDouble(getString(R.string.key_treatments_safety_max_bolus), 3.0) - val buttons = listOf(Pair(R.id.plusbutton, 0.1), Pair(R.id.plusbutton2, increment1), Pair(R.id.plusbutton3, increment2)) // When taken form phone settings round. - editInsulin = PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, initValue, 0.0, maxBolus, 0.1, DecimalFormat("#0.0"), false) - setLabelToPlusMinusView(view, getString(R.string.action_insulin)) + val title = getString(R.string.action_insulin) + editInsulin = PlusMinusEditText(viewAdapter, initValue, 0.0, maxBolus, stepValues, DecimalFormat("#0.0"), false, title) + val view = viewAdapter.root container.addView(view) view.requestFocus() - } else { - view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) + view + } + + else -> { + val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) val confirmButton = view.findViewById(R.id.confirmbutton) confirmButton.setOnClickListener { rxBus.send(EventWearToMobile(ActionBolusPreCheck(SafeParse.stringToDouble(editInsulin?.editText?.text.toString()), 0))) @@ -58,8 +61,8 @@ class BolusActivity : ViewSelectorActivity() { finishAffinity() } container.addView(view) + view } - return view } override fun destroyItem(container: ViewGroup, row: Int, col: Int, view: Any) { diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/CarbActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/CarbActivity.kt index 7de9a45dd3..b941049002 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/CarbActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/CarbActivity.kt @@ -10,6 +10,7 @@ import android.view.ViewGroup import android.widget.ImageView import info.nightscout.androidaps.R import info.nightscout.androidaps.events.EventWearToMobile +import info.nightscout.androidaps.interaction.utils.EditPlusMinusViewAdapter import info.nightscout.androidaps.interaction.utils.PlusMinusEditText import info.nightscout.shared.SafeParse import info.nightscout.shared.weardata.EventData.ActionECarbsPreCheck @@ -32,26 +33,28 @@ class CarbActivity : ViewSelectorActivity() { val increment1 = sp.getInt(R.string.key_carbs_button_increment_1, 5).toDouble() val increment2 = sp.getInt(R.string.key_carbs_button_increment_2, 10).toDouble() + val stepValues = listOf(1.0, increment1, increment2) override fun getColumnCount(arg0: Int): Int = 2 override fun getRowCount(): Int = 1 - override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { - val view: View - if (col == 0) { - view = getInflatedPlusMinusView(container, true) + override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when (col) { + 0 -> { + val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, true) + val view = viewAdapter.root var def = 0.0 if (editCarbs != null) { def = SafeParse.stringToDouble(editCarbs?.editText?.text.toString()) } val maxCarbs = sp.getInt(getString(R.string.key_treatments_safety_max_carbs), 48) - val buttons = listOf(Pair(R.id.plusbutton, 1.0), Pair(R.id.plusbutton2, increment1), Pair(R.id.plusbutton3, increment2)) - editCarbs = PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), true) - setLabelToPlusMinusView(view, getString(R.string.action_carbs)) + editCarbs = PlusMinusEditText(viewAdapter, def, 0.0, maxCarbs.toDouble(), stepValues, DecimalFormat("0"), true, getString(R.string.action_carbs)) container.addView(view) view.requestFocus() - } else { - view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) + view + } + + else -> { + val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) val confirmButton = view.findViewById(R.id.confirmbutton) confirmButton.setOnClickListener { // With start time 0 and duration 0 @@ -61,8 +64,8 @@ class CarbActivity : ViewSelectorActivity() { finishAffinity() } container.addView(view) + view } - return view } override fun destroyItem(container: ViewGroup, row: Int, col: Int, view: Any) { diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ECarbActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ECarbActivity.kt index 50988562a4..0a643e9bff 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ECarbActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ECarbActivity.kt @@ -10,6 +10,7 @@ import android.view.ViewGroup import android.widget.ImageView import info.nightscout.androidaps.R import info.nightscout.androidaps.events.EventWearToMobile +import info.nightscout.androidaps.interaction.utils.EditPlusMinusViewAdapter import info.nightscout.androidaps.interaction.utils.PlusMinusEditText import info.nightscout.shared.SafeParse.stringToDouble import info.nightscout.shared.SafeParse.stringToInt @@ -36,44 +37,50 @@ class ECarbActivity : ViewSelectorActivity() { override fun getColumnCount(arg0: Int): Int = 4 override fun getRowCount(): Int = 1 - private val increment1 = sp.getInt(R.string.key_carbs_button_increment_1, 5).toDouble() - private val increment2 = sp.getInt(R.string.key_carbs_button_increment_2, 10).toDouble() + val increment1 = sp.getInt(R.string.key_carbs_button_increment_1, 5).toDouble() + val increment2 = sp.getInt(R.string.key_carbs_button_increment_2, 10).toDouble() + val stepValues = listOf(1.0, increment1, increment2) - override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { - return if (col == 0) { - val view = getInflatedPlusMinusView(container, true) + override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when (col) { + 0 -> { + val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, true) + val view = viewAdapter.root var def = 0.0 if (editCarbs != null) { def = stringToDouble(editCarbs?.editText?.text.toString()) } val maxCarbs = sp.getInt(getString(R.string.key_treatments_safety_max_carbs), 48) - val buttons = listOf(Pair(R.id.plusbutton, 1.0), Pair(R.id.plusbutton2, increment1), Pair(R.id.plusbutton3, increment2)) - editCarbs = PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), true) - setLabelToPlusMinusView(view, getString(R.string.action_carbs)) + editCarbs = PlusMinusEditText(viewAdapter, def, 0.0, maxCarbs.toDouble(), stepValues, DecimalFormat("0"), true, getString(R.string.action_carbs)) container.addView(view) view.requestFocus() view - } else if (col == 1) { - val view = getInflatedPlusMinusView(container) + } + + 1 -> { + val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false) + val view = viewAdapter.root var def = 0.0 if (editStartTime != null) { def = stringToDouble(editStartTime?.editText?.text.toString()) } - editStartTime = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, -60.0, 300.0, 15.0, DecimalFormat("0"), false) - setLabelToPlusMinusView(view, getString(R.string.action_start_min)) + editStartTime = PlusMinusEditText(viewAdapter, 15.0, def, -60.0, 300.0, DecimalFormat("0"), false, getString(R.string.action_start_min)) container.addView(view) view - } else if (col == 2) { - val view = getInflatedPlusMinusView(container) + } + + 2 -> { + val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false) + val view = viewAdapter.root var def = 0.0 if (editDuration != null) { def = stringToDouble(editDuration?.editText?.text.toString()) } - editDuration = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 0.0, 8.0, 1.0, DecimalFormat("0"), false) - setLabelToPlusMinusView(view, getString(R.string.action_duration_h)) + editDuration = PlusMinusEditText(viewAdapter, 1.0, def, 0.0, 8.0, DecimalFormat("0"), false, getString(R.string.action_duration_h)) container.addView(view) view - } else { + } + + else -> { val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) val confirmButton = view.findViewById(R.id.confirmbutton) confirmButton.setOnClickListener { @@ -102,4 +109,4 @@ class ECarbActivity : ViewSelectorActivity() { override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object` } -} +} \ No newline at end of file diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/FillActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/FillActivity.kt index a10163e466..2525033df0 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/FillActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/FillActivity.kt @@ -10,6 +10,7 @@ import android.view.ViewGroup import android.widget.ImageView import info.nightscout.androidaps.R import info.nightscout.androidaps.events.EventWearToMobile +import info.nightscout.androidaps.interaction.utils.EditPlusMinusViewAdapter import info.nightscout.androidaps.interaction.utils.PlusMinusEditText import info.nightscout.shared.SafeParse.stringToDouble import info.nightscout.shared.weardata.EventData.ActionFillPreCheck @@ -33,19 +34,21 @@ class FillActivity : ViewSelectorActivity() { override fun getColumnCount(arg0: Int): Int = 2 override fun getRowCount(): Int = 1 - override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { - return if (col == 0) { - val view = getInflatedPlusMinusView(container) + override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when (col) { + 0 -> { + val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false) + val view = viewAdapter.root var def = 0.0 if (editInsulin != null) { def = stringToDouble(editInsulin?.editText?.text.toString()) } - editInsulin = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 0.0, 30.0, 0.1, DecimalFormat("#0.0"), false) - setLabelToPlusMinusView(view, getString(R.string.action_insulin)) + editInsulin = PlusMinusEditText(viewAdapter, def, 0.0, 30.0, 0.1, DecimalFormat("#0.0"), false, getString(R.string.action_insulin)) container.addView(view) view.requestFocus() view - } else { + } + + else -> { val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) val confirmButton = view.findViewById(R.id.confirmbutton) confirmButton.setOnClickListener { @@ -68,4 +71,4 @@ class FillActivity : ViewSelectorActivity() { override fun isViewFromObject(view: View, `object`: Any): Boolean = view === `object` } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ProfileSwitchActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ProfileSwitchActivity.kt index 73b9551b53..c6498f2638 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ProfileSwitchActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ProfileSwitchActivity.kt @@ -10,6 +10,7 @@ import android.view.ViewGroup import android.widget.ImageView import info.nightscout.androidaps.R import info.nightscout.androidaps.events.EventWearToMobile +import info.nightscout.androidaps.interaction.utils.EditPlusMinusViewAdapter import info.nightscout.androidaps.interaction.utils.PlusMinusEditText import info.nightscout.shared.SafeParse import info.nightscout.shared.weardata.EventData.ActionProfileSwitchPreCheck @@ -43,29 +44,34 @@ class ProfileSwitchActivity : ViewSelectorActivity() { override fun getColumnCount(arg0: Int): Int = 3 override fun getRowCount(): Int = 1 - override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { - return if (col == 0) { - val view = getInflatedPlusMinusView(container) + override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when (col) { + 0 -> { + val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false) + val view = viewAdapter.root var def = timeshift.toDouble() if (editTimeshift != null) { def = SafeParse.stringToDouble(editTimeshift?.editText?.text.toString()) } - editTimeshift = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 0.0, 23.0, 1.0, DecimalFormat("0"), true, true) - setLabelToPlusMinusView(view, getString(R.string.action_timeshift)) + editTimeshift = PlusMinusEditText(viewAdapter, def, 0.0, 23.0, 1.0, DecimalFormat("0"), true, getString(R.string.action_timeshift), true) container.addView(view) view.requestFocus() view - } else if (col == 1) { - val view = getInflatedPlusMinusView(container) + } + + 1 -> { + val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false) + val view = viewAdapter.root var def = percentage.toDouble() if (editPercentage != null) { def = SafeParse.stringToDouble(editPercentage?.editText?.text.toString()) } - editPercentage = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 30.0, 250.0, 1.0, DecimalFormat("0"), false) - setLabelToPlusMinusView(view, getString(R.string.action_percentage)) + editPercentage = PlusMinusEditText(viewAdapter, def, 30.0, 250.0, 1.0, DecimalFormat("0"), false, getString(R.string.action_percentage)) + container.addView(view) view - } else { + } + + else -> { val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) val confirmButton = view.findViewById(R.id.confirmbutton) confirmButton.setOnClickListener { diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TempTargetActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TempTargetActivity.kt index cab25b52eb..26570a6bdd 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TempTargetActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TempTargetActivity.kt @@ -10,6 +10,7 @@ import android.view.ViewGroup import android.widget.ImageView import info.nightscout.androidaps.R import info.nightscout.androidaps.events.EventWearToMobile +import info.nightscout.androidaps.interaction.utils.EditPlusMinusViewAdapter import info.nightscout.androidaps.interaction.utils.PlusMinusEditText import info.nightscout.shared.SafeParse import info.nightscout.shared.weardata.EventData.ActionTempTargetPreCheck @@ -45,49 +46,56 @@ class TempTargetActivity : ViewSelectorActivity() { return 1 } - override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { - return if (col == 0) { - val view = getInflatedPlusMinusView(container) + override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when { + col == 0 -> { + val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false) + val view = viewAdapter.root time = if (time == null) { - PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, 60.0, 0.0, 24 * 60.0, 5.0, DecimalFormat("0"), false) + PlusMinusEditText(viewAdapter, 60.0, 0.0, 24 * 60.0, 5.0, DecimalFormat("0"), false, getString(R.string.action_duration)) } else { val def = SafeParse.stringToDouble(time?.editText?.text.toString()) - PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 0.0, 24 * 60.0, 5.0, DecimalFormat("0"), false) + PlusMinusEditText(viewAdapter, def, 0.0, 24 * 60.0, 5.0, DecimalFormat("0"), false, getString(R.string.action_duration)) } - setLabelToPlusMinusView(view, getString(R.string.action_duration)) container.addView(view) view.requestFocus() view - } else if (col == 1) { - val view = getInflatedPlusMinusView(container) + } + + col == 1 -> { + val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false) + val view = viewAdapter.root + val title = if (isSingleTarget) getString(R.string.action_target) else getString(R.string.action_low) if (isMGDL) { var def = 100.0 if (lowRange != null) def = SafeParse.stringToDouble(lowRange?.editText?.text.toString()) - lowRange = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 72.0, 180.0, 1.0, DecimalFormat("0"), false) + lowRange = PlusMinusEditText(viewAdapter, def, 72.0, 180.0, 1.0, DecimalFormat("0"), false, title) } else { var def = 5.5 if (lowRange != null) def = SafeParse.stringToDouble(lowRange?.editText?.text.toString()) - lowRange = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 4.0, 10.0, 0.1, DecimalFormat("#0.0"), false) + lowRange = PlusMinusEditText(viewAdapter, def, 4.0, 10.0, 0.1, DecimalFormat("#0.0"), false, title) } - if (isSingleTarget) setLabelToPlusMinusView(view, getString(R.string.action_target)) - else setLabelToPlusMinusView(view, getString(R.string.action_low)) + container.addView(view) view - } else if (col == 2 && !isSingleTarget) { - val view = getInflatedPlusMinusView(container) + } + + col == 2 && !isSingleTarget -> { + val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false) + val view = viewAdapter.root if (isMGDL) { var def = 100.0 if (highRange != null) def = SafeParse.stringToDouble(highRange?.editText?.text.toString()) - highRange = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 72.0, 180.0, 1.0, DecimalFormat("0"), false) + highRange = PlusMinusEditText(viewAdapter, def, 72.0, 180.0, 1.0, DecimalFormat("0"), false, getString(R.string.action_high)) } else { var def = 5.5 if (highRange != null) def = SafeParse.stringToDouble(highRange?.editText?.text.toString()) - highRange = PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 4.0, 10.0, 0.1, DecimalFormat("#0.0"), false) + highRange = PlusMinusEditText(viewAdapter, def, 4.0, 10.0, 0.1, DecimalFormat("#0.0"), false, getString(R.string.action_high)) } - setLabelToPlusMinusView(view, getString(R.string.action_high)) container.addView(view) view - } else { + } + + else -> { val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) val confirmButton = view.findViewById(R.id.confirmbutton) confirmButton.setOnClickListener { @@ -119,4 +127,4 @@ class TempTargetActivity : ViewSelectorActivity() { return view === `object` } } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TreatmentActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TreatmentActivity.kt index 630317b89a..55805803d4 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TreatmentActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TreatmentActivity.kt @@ -10,6 +10,7 @@ import android.view.ViewGroup import android.widget.ImageView import info.nightscout.androidaps.R import info.nightscout.androidaps.events.EventWearToMobile +import info.nightscout.androidaps.interaction.utils.EditPlusMinusViewAdapter import info.nightscout.androidaps.interaction.utils.PlusMinusEditText import info.nightscout.shared.SafeParse.stringToDouble import info.nightscout.shared.SafeParse.stringToInt @@ -38,32 +39,37 @@ class TreatmentActivity : ViewSelectorActivity() { val incrementInsulin1 = (sp.getDouble(R.string.key_insulin_button_increment_1, 0.5) * 10).roundToInt() / 10.0 val incrementInsulin2 = (sp.getDouble(R.string.key_insulin_button_increment_2, 1.0) * 10).roundToInt() / 10.0 + val stepValuesInsulin = listOf(0.1, incrementInsulin1, incrementInsulin2) val incrementCarbs1 = sp.getInt(R.string.key_carbs_button_increment_1, 5).toDouble() val incrementCarbs2 = sp.getInt(R.string.key_carbs_button_increment_2, 10).toDouble() + val stepValuesCarbs = listOf(1.0, incrementCarbs1, incrementCarbs2) - override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { - return if (col == 0) { - val view = getInflatedPlusMinusView(container, true) + override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when (col) { + 0 -> { + val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, true) + val view = viewAdapter.root var def = 0.0 if (editInsulin != null) def = stringToDouble(editInsulin?.editText?.text.toString()) val maxBolus = sp.getDouble(getString(R.string.key_treatments_safety_max_bolus), 3.0) - val buttons = listOf(Pair(R.id.plusbutton, 0.1), Pair(R.id.plusbutton2, incrementInsulin1), Pair(R.id.plusbutton3, incrementInsulin2)) - editInsulin = PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, def, 0.0, maxBolus, 0.1, DecimalFormat("#0.0"), false) - setLabelToPlusMinusView(view, getString(R.string.action_insulin)) + editInsulin = PlusMinusEditText(viewAdapter, def, 0.0, maxBolus, stepValuesInsulin, DecimalFormat("#0.0"), false, getString(R.string.action_insulin)) container.addView(view) view.requestFocus() view - } else if (col == 1) { - val view = getInflatedPlusMinusView(container, true) + } + + 1 -> { + val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, true) + val view = viewAdapter.root var def = 0.0 val maxCarbs = sp.getInt(getString(R.string.key_treatments_safety_max_carbs), 48) if (editCarbs != null) def = stringToDouble(editCarbs?.editText?.text.toString()) - val buttons = listOf(Pair(R.id.plusbutton, 1.0), Pair(R.id.plusbutton2, incrementCarbs1), Pair(R.id.plusbutton3, incrementCarbs2)) - editCarbs = PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false) - setLabelToPlusMinusView(view, getString(R.string.action_carbs)) + + editCarbs = PlusMinusEditText(viewAdapter, def, 0.0, maxCarbs.toDouble(), stepValuesCarbs, DecimalFormat("0"), false, getString(R.string.action_carbs)) container.addView(view) view - } else { + } + + else -> { val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) val confirmButton = view.findViewById(R.id.confirmbutton) confirmButton.setOnClickListener { diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ViewSelectorActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ViewSelectorActivity.kt index eb3a9b70d7..d1d3b19099 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ViewSelectorActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ViewSelectorActivity.kt @@ -73,22 +73,6 @@ open class ViewSelectorActivity : DaggerActivity() { } } - fun getInflatedPlusMinusView(container: ViewGroup?, mulitple: Boolean = false): View { - val layoutRight = if (mulitple) R.layout.action_editplusminus_item_quickrighty_plus else R.layout.action_editplusminus_item_quickrighty - val layoutLeft = if (mulitple) R.layout.action_editplusminus_item_quicklefty_plus else R.layout.action_editplusminus_item_quicklefty - return when (sp.getInt(R.string.key_input_design, 1)) { - 2 -> LayoutInflater.from(applicationContext).inflate(layoutRight, container, false) - 3 -> LayoutInflater.from(applicationContext).inflate(layoutLeft, container, false) - 4 -> LayoutInflater.from(applicationContext).inflate(R.layout.action_editplusminus_item_viktoria, container, false) - else -> LayoutInflater.from(applicationContext).inflate(R.layout.action_editplusminus_item, container, false) - } - } - - fun setLabelToPlusMinusView(view: View, labelText: String?) { - val textView = view.findViewById(R.id.label) - textView.text = labelText - } - fun showToast(context: Context?, text: Int) { Toast.makeText(context, getString(text), Toast.LENGTH_LONG).show() } diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/WizardActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/WizardActivity.kt index dfd6e6291b..9a9bd01967 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/WizardActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/WizardActivity.kt @@ -10,6 +10,7 @@ import android.view.ViewGroup import android.widget.ImageView import info.nightscout.androidaps.R import info.nightscout.androidaps.events.EventWearToMobile +import info.nightscout.androidaps.interaction.utils.EditPlusMinusViewAdapter import info.nightscout.androidaps.interaction.utils.PlusMinusEditText import info.nightscout.shared.SafeParse import info.nightscout.shared.weardata.EventData.ActionWizardPreCheck @@ -37,35 +38,39 @@ class WizardActivity : ViewSelectorActivity() { override fun getRowCount(): Int = 1 private val increment1 = sp.getInt(R.string.key_carbs_button_increment_1, 5).toDouble() private val increment2 = sp.getInt(R.string.key_carbs_button_increment_2, 10).toDouble() + val stepValues = listOf(1.0, increment1, increment2) - override fun instantiateItem(container: ViewGroup, row: Int, col: Int): Any { - return if (col == 0) { - val view = getInflatedPlusMinusView(container, true) + override fun instantiateItem(container: ViewGroup, row: Int, col: Int): View = when { + col == 0 -> { + val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, true) + val view = viewAdapter.root val maxCarbs = sp.getInt(getString(R.string.key_treatments_safety_max_carbs), 48) - val buttons = listOf(Pair(R.id.plusbutton, 1.0), Pair(R.id.plusbutton2, increment1), Pair(R.id.plusbutton3, increment2)) editCarbs = if (editCarbs == null) { - PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, 0.0, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false) + PlusMinusEditText(viewAdapter, 0.0, 0.0, maxCarbs.toDouble(), stepValues, DecimalFormat("0"), false, getString(R.string.action_carbs)) } else { val def = SafeParse.stringToDouble(editCarbs?.editText?.text.toString()) - PlusMinusEditText(view, R.id.amountfield, buttons, R.id.minusbutton, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false) + PlusMinusEditText(viewAdapter, def, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false, getString(R.string.action_carbs)) } - setLabelToPlusMinusView(view, getString(R.string.action_carbs)) container.addView(view) view.requestFocus() view - } else if (col == 1 && hasPercentage) { - val view = getInflatedPlusMinusView(container) + } + + col == 1 && hasPercentage -> { + val viewAdapter = EditPlusMinusViewAdapter.getViewAdapter(sp, applicationContext, container, false) + val view = viewAdapter.root val percentage = sp.getInt(getString(R.string.key_bolus_wizard_percentage), 100) editPercentage = if (editPercentage == null) { - PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, percentage.toDouble(), 50.0, 150.0, 1.0, DecimalFormat("0"), false) + PlusMinusEditText(viewAdapter, percentage.toDouble(), 50.0, 150.0, 1.0, DecimalFormat("0"), false, getString(R.string.action_percentage)) } else { val def = SafeParse.stringToDouble(editPercentage?.editText?.text.toString()) - PlusMinusEditText(view, R.id.amountfield, R.id.plusbutton, R.id.minusbutton, def, 50.0, 150.0, 1.0, DecimalFormat("0"), false) + PlusMinusEditText(viewAdapter, def, 50.0, 150.0, 1.0, DecimalFormat("0"), false, getString(R.string.action_percentage)) } - setLabelToPlusMinusView(view, getString(R.string.action_percentage)) container.addView(view) view - } else { + } + + else -> { val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) view.findViewById(R.id.confirmbutton) .setOnClickListener { diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt index 4b3798940b..a1de3f1e9d 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt @@ -2,10 +2,10 @@ package info.nightscout.androidaps.interaction.utils import android.content.Context import android.view.LayoutInflater -import android.view.View import android.view.ViewGroup import info.nightscout.androidaps.R import info.nightscout.androidaps.databinding.ActionEditplusminusItemBinding +import info.nightscout.androidaps.databinding.ActionEditplusminusItemPlusBinding import info.nightscout.androidaps.databinding.ActionEditplusminusItemQuickleftyPlusBinding import info.nightscout.androidaps.databinding.ActionEditplusminusItemQuickleftyBinding import info.nightscout.androidaps.databinding.ActionEditplusminusItemQuickrightyBinding @@ -14,65 +14,84 @@ import info.nightscout.androidaps.databinding.ActionEditplusminusItemViktoriaBin import info.nightscout.shared.sharedPreferences.SP /** - * NumberPickerViewAdapter binds both NumberPickerLayoutBinding and NumberPickerLayoutVerticalBinding shared attributes to one common view adapter. + * EditPlusMinusViewAdapter binds both ActionEditplusminusItemBinding variants shared attributes to one common view adapter. * Requires at least one of the ViewBinding as a parameter. Recommended to use the factory object to create the binding. */ class EditPlusMinusViewAdapter( - val eS: ActionEditplusminusItemBinding?, - val eQLP: ActionEditplusminusItemQuickleftyPlusBinding?, - val eQL: ActionEditplusminusItemQuickleftyBinding?, - val eQRP: ActionEditplusminusItemQuickleftyPlusBinding?, - val qQR: ActionEditplusminusItemQuickrightyBinding?, - val nQRP: ActionEditplusminusItemQuickrightyPlusBinding?, - val eV: ActionEditplusminusItemViktoriaBinding? + eD: ActionEditplusminusItemBinding?, + eDP: ActionEditplusminusItemPlusBinding?, + eQL: ActionEditplusminusItemQuickleftyBinding?, + eQLP: ActionEditplusminusItemQuickleftyPlusBinding?, + eQR: ActionEditplusminusItemQuickrightyBinding?, + eQRP: ActionEditplusminusItemQuickrightyPlusBinding?, + eV: ActionEditplusminusItemViktoriaBinding? ) { init { - if (eS == null && eQLP == null && eQL == null && eQRP == null && qQR == null && nQRP == null && eV == null) { + if (eD == null && eDP == null && eQL == null && eQLP == null && eQR == null && eQRP == null && eV == null) { throw IllegalArgumentException("Require at least on Binding parameter") } } - val amountField = - eS?.amountfield ?: eQLP?.amountfield ?: eQL?.amountfield ?: eQRP?.amountfield ?: qQR?.amountfield ?: nQRP?.amountfield ?: eV?.amountfield + val editText = + eD?.editText ?: eDP?.editText ?: eQL?.editText ?: eQLP?.editText ?: eQR?.editText ?: eQRP?.editText ?: eV?.editText ?: throw IllegalArgumentException("Missing require View Binding parameter display") val minusButton = - eS?.minusbutton ?: eQLP?.minusbutton ?: eQL?.minusbutton ?: eQRP?.minusbutton ?: qQR?.minusbutton ?: nQRP?.minusbutton ?: eV?.minusbutton + eD?.minusButton ?: eDP?.minusButton ?: eQL?.minusButton ?: eQLP?.minusButton ?: eQR?.minusButton ?: eQRP?.minusButton ?: eV?.minusButton ?: throw IllegalArgumentException("Missing require View Binding parameter display") - val plusButton = - eS?.plusbutton ?: eQLP?.plusbutton ?: eQL?.plusbutton ?: eQRP?.plusbutton ?: qQR?.plusbutton ?: nQRP?.plusbutton ?: eV?.plusbutton + val plusButton1 = + eD?.plusButton1 ?: eDP?.plusButton1 ?: eQL?.plusButton1 ?: eQLP?.plusButton1 ?: eQR?.plusButton1 ?: eQRP?.plusButton1 ?: eV?.plusButton1 ?: throw IllegalArgumentException("Missing require View Binding parameter display") val label = - eS?.label ?: eQLP?.label ?: eQL?.label ?: eQRP?.label ?: qQR?.label ?: nQRP?.label ?: eV?.label + eD?.label ?: eDP?.label ?: eQL?.label ?: eQLP?.label ?: eQR?.label ?: eQRP?.label ?: eV?.label ?: throw IllegalArgumentException("Missing require View Binding parameter display") - val plusButton2 = eQLP?.plusbutton2 ?: eQRP?.plusbutton2 - val plusButton3 = eQLP?.plusbutton3 ?: eQRP?.plusbutton3 + val plusButton2 = eDP?.plusButton2 ?: eQLP?.plusButton2 ?: eQRP?.plusButton2 + val plusButton3 = eDP?.plusButton3 ?: eQLP?.plusButton3 ?: eQRP?.plusButton3 val root = - eS?.root ?: eQLP?.root ?: eQL?.root ?: eQRP?.root ?: qQR?.root ?: nQRP?.root ?: eV?.root + eD?.root ?: eDP?.root ?: eQL?.root ?: eQLP?.root ?: eQR?.root ?: eQRP?.root ?: eV?.root ?: throw IllegalArgumentException("Missing require View Binding parameter display") companion object { - fun getInflatedPlusMinusView(sp: SP, context: Context, container: ViewGroup?, mulitple: Boolean = false): EditPlusMinusViewAdapter { + fun getViewAdapter(sp: SP, context: Context, container: ViewGroup?, multiple: Boolean = false): EditPlusMinusViewAdapter { val inflater = LayoutInflater.from(context) - val bindLayout = ActionEditplusminusItemBinding.inflate(inflater, container, false) - val binding = EditPlusMinusViewAdapter(bindLayout, null, null, null, null, null, null) - return binding - // val layoutRight = if (mulitple) R.layout.action_editplusminus_item_quickrighty_plus else R.layout.action_editplusminus_item_quickrighty - // val layoutLeft = if (mulitple) R.layout.action_editplusminus_item_quicklefty_plus else R.layout.action_editplusminus_item_quicklefty - // return when (sp.getInt(R.string.key_input_design, 1)) { - // 2 -> LayoutInflater.from(applicationContext).inflate(layoutRight, container, false) - // 3 -> LayoutInflater.from(applicationContext).inflate(layoutLeft, container, false) - // 4 -> LayoutInflater.from(applicationContext).inflate(R.layout.action_editplusminus_item_viktoria, container, false) - // else -> LayoutInflater.from(applicationContext).inflate(R.layout.action_editplusminus_item, container, false) - // } + + return when (sp.getInt(R.string.key_input_design, 1)) { + 2 -> { + if (multiple) { + val bindLayout = ActionEditplusminusItemQuickrightyPlusBinding.inflate(inflater, container, false) + EditPlusMinusViewAdapter(null, null, null, null, null, bindLayout, null) + } else { + val bindLayout = ActionEditplusminusItemQuickrightyBinding.inflate(inflater, container, false) + EditPlusMinusViewAdapter(null, null, null, null, bindLayout, null, null) + } + } + + 3 -> { + if (multiple) { + val bindLayout = ActionEditplusminusItemQuickleftyPlusBinding.inflate(inflater, container, false) + EditPlusMinusViewAdapter(null, null, null, bindLayout, null, null, null) + } else { + val bindLayout = ActionEditplusminusItemQuickleftyBinding.inflate(inflater, container, false) + EditPlusMinusViewAdapter(null, null, bindLayout, null, null, null, null) + } + } + + 4 -> { + val bindLayout = ActionEditplusminusItemViktoriaBinding.inflate(inflater, container, false) + EditPlusMinusViewAdapter(null, null, null, null, null, null, bindLayout) + } + + else -> { + if (multiple) { + val bindLayout = ActionEditplusminusItemPlusBinding.inflate(inflater, container, false) + EditPlusMinusViewAdapter(null, bindLayout, null, null, null, null, null) + } else { + val bindLayout = ActionEditplusminusItemBinding.inflate(inflater, container, false) + EditPlusMinusViewAdapter(bindLayout, null, null, null, null, null, null) + } + } + } } - // fun getBinding(bindLayout: NumberPickerLayoutBinding): NumberPickerViewAdapter { - // return NumberPickerViewAdapter(bindLayout, null) - // } - // - // fun getBinding(bindLayout: NumberPickerLayoutVerticalBinding): NumberPickerViewAdapter { - // return NumberPickerViewAdapter(null, bindLayout) - // } } -} \ No newline at end of file +} diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt index f812b7e245..2430c9e677 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt @@ -9,7 +9,6 @@ import android.view.View import android.view.View.OnGenericMotionListener import android.view.View.OnTouchListener import android.widget.TextView -import androidx.appcompat.widget.AppCompatButton import androidx.core.view.InputDeviceCompat import androidx.core.view.MotionEventCompat import java.text.DecimalFormat @@ -17,47 +16,38 @@ import java.text.NumberFormat import java.util.concurrent.Executors import java.util.concurrent.ScheduledExecutorService import java.util.concurrent.TimeUnit -import kotlin.Pair /** * Created by mike on 28.06.2016. */ @SuppressLint("SetTextI18n") class PlusMinusEditText @JvmOverloads constructor( - view: View, - editTextID: Int, - private var plusButtons: List>, - minusID: Int, + private val binding: EditPlusMinusViewAdapter, initValue: Double, private val minValue: Double, private val maxValue: Double, - private val stepGeneral: Double, + private val stepValues: List, private val formatter: NumberFormat, private val allowZero: Boolean, + label: String, private val roundRobin: Boolean = false, ) : View.OnKeyListener, OnTouchListener, View.OnClickListener, OnGenericMotionListener { constructor( - view: View, - editTextID: Int, - plusID: Int, - minusID: Int, + binding: EditPlusMinusViewAdapter, initValue: Double, minValue: Double, maxValue: Double, - stepGeneral: Double, + step: Double, formatter: NumberFormat, allowZero: Boolean, + label: String, roundRobin: Boolean = false - ) : this(view, editTextID, listOf(Pair(plusID, stepGeneral)), minusID, initValue, minValue, maxValue, stepGeneral, formatter, allowZero, roundRobin) + ) : this(binding, initValue, minValue, maxValue, listOf(step), formatter, allowZero, label, roundRobin) + private val stepGeneral: Double = stepValues[0] var editText: TextView private set - private var minusImage: View - private var plusImage1: View - private var plusImage2: AppCompatButton? = null - private var plusImage3: AppCompatButton? = null private var value: Double - private val context: Context private var mChangeCounter = 0 private var mLastChange: Long = 0 private val mHandler: Handler @@ -70,11 +60,11 @@ import kotlin.Pair override fun run() { val msg = Message() val doubleLimit = 5 - val multipleButtons = mInc && (plusImage2 != null || plusImage3 != null) + val multipleButtons = mInc && (binding.plusButton2 != null || binding.plusButton3 != null) if (!multipleButtons && repeated % doubleLimit == 0) multiplier *= 2 val bundle = Bundle() - bundle.putDouble("step", step) - bundle.putInt("multiplier", multiplier) + bundle.putDouble(STEP, step) + bundle.putInt(MULTIPLIER, multiplier) msg.data = bundle if (mInc) { @@ -114,14 +104,14 @@ import kotlin.Pair if (vibrate) vibrateDevice() } - fun vibrateDevice() { + private fun vibrateDevice() { val vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { val vibratorManager = - context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager + binding.root.context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager vibratorManager.defaultVibrator } else { @Suppress("DEPRECATION") - context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator + binding.root.context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { @@ -155,19 +145,19 @@ import kotlin.Pair private fun getStep(v: View): Double { return when (v) { - plusImage1 -> plusButtons[0].second - plusImage2 -> plusButtons[1].second - plusImage3 -> plusButtons[2].second - else -> stepGeneral + binding.plusButton1 -> stepValues[0] + binding.plusButton2 -> stepValues[1] + binding.plusButton3 -> stepValues[2] + else -> stepValues[0] } } private fun isIncrement(v: View): Boolean { return when (v) { - plusImage1 -> true - plusImage2 -> true - plusImage3 -> true - else -> false + binding.plusButton1 -> true + binding.plusButton2 -> true + binding.plusButton3 -> true + else -> false } } @@ -229,30 +219,22 @@ import kotlin.Pair private const val THRESHOLD_TIME = 100 private const val MSG_INC = 0 private const val MSG_DEC = 1 + private const val STEP = "step" + private const val MULTIPLIER = "multiplier" } init { - context = view.context - editText = view.findViewById(editTextID) - minusImage = view.findViewById(minusID) - plusImage1 = view.findViewById(plusButtons.first().first) + editText = binding.editText + binding.label.text = label val format = DecimalFormat("#.#") - plusButtons.getOrNull(1)?.let { - plusImage2 = view.findViewById(it.first) - plusImage2?.text = "+${format.format(it.second).replaceFirst("^0+(?!$)".toRegex(), "")}" - plusImage2?.visibility = View.VISIBLE - } - plusButtons.getOrNull(2)?.let { - plusImage3 = view.findViewById(it.first) - plusImage3?.text = "+${format.format(it.second).replaceFirst("^0+(?!$)".toRegex(), "")}" - plusImage3?.visibility = View.VISIBLE - } + binding.plusButton2?.text = "+${format.format(stepValues[1]).replaceFirst("^0+(?!$)".toRegex(), "")}" + binding.plusButton3?.text = "+${format.format(stepValues[2]).replaceFirst("^0+(?!$)".toRegex(), "")}" value = initValue mHandler = object : Handler(Looper.getMainLooper()) { override fun handleMessage(msg: Message) { - val multiplier = msg.data.getInt("multiplier") - val step = msg.data.getDouble("step") + val multiplier = msg.data.getInt(MULTIPLIER) + val step = msg.data.getDouble(STEP) when (msg.what) { MSG_INC -> { @@ -271,18 +253,18 @@ import kotlin.Pair editText.showSoftInputOnFocus = false editText.setTextIsSelectable(false) - minusImage.setOnTouchListener(this) - minusImage.setOnKeyListener(this) - minusImage.setOnClickListener(this) - plusImage1.setOnTouchListener(this) - plusImage1.setOnKeyListener(this) - plusImage1.setOnClickListener(this) - plusImage2?.setOnTouchListener(this) - plusImage2?.setOnKeyListener(this) - plusImage2?.setOnClickListener(this) - plusImage3?.setOnTouchListener(this) - plusImage3?.setOnKeyListener(this) - plusImage3?.setOnClickListener(this) + binding.minusButton.setOnTouchListener(this) + binding.minusButton.setOnKeyListener(this) + binding.minusButton.setOnClickListener(this) + binding.plusButton1.setOnTouchListener(this) + binding.plusButton1.setOnKeyListener(this) + binding.plusButton1.setOnClickListener(this) + binding.plusButton2?.setOnTouchListener(this) + binding.plusButton2?.setOnKeyListener(this) + binding.plusButton2?.setOnClickListener(this) + binding.plusButton3?.setOnTouchListener(this) + binding.plusButton3?.setOnKeyListener(this) + binding.plusButton3?.setOnClickListener(this) editText.setOnGenericMotionListener(this) updateEditText() } diff --git a/wear/src/main/res/layout/action_editplusminus_item.xml b/wear/src/main/res/layout/action_editplusminus_item.xml index 5c5b8856d5..75c3b21594 100644 --- a/wear/src/main/res/layout/action_editplusminus_item.xml +++ b/wear/src/main/res/layout/action_editplusminus_item.xml @@ -1,67 +1,131 @@ - + android:layout_height="match_parent"> - + + + + + + + android:tint="@color/white" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintCircle="@+id/center" + app:layout_constraintCircleAngle="145" + app:layout_constraintCircleRadius="70dp" + app:layout_constraintLeft_toLeftOf="parent" /> - + + + + + android:layout_marginBottom="8dp" + android:background="@drawable/circle" + android:backgroundTint="@color/gray_700" + android:contentDescription="@string/increment" + app:layout_constraintBottom_toTopOf="@+id/minus_button" + app:layout_constraintCircle="@+id/center" + app:layout_constraintCircleAngle="55" + app:layout_constraintCircleRadius="40dp" + app:layout_constraintRight_toLeftOf="@id/plus_button1"> - - - - - + + android:tint="@color/white" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintCircle="@+id/center" + app:layout_constraintCircleAngle="215" + app:layout_constraintCircleRadius="70dp" + app:layout_constraintRight_toRightOf="parent" /> - + diff --git a/wear/src/main/res/layout/action_editplusminus_item_plus.xml b/wear/src/main/res/layout/action_editplusminus_item_plus.xml new file mode 100644 index 0000000000..18ea44cc13 --- /dev/null +++ b/wear/src/main/res/layout/action_editplusminus_item_plus.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/wear/src/main/res/layout/action_editplusminus_item_quicklefty.xml b/wear/src/main/res/layout/action_editplusminus_item_quicklefty.xml index d96ae1d26f..d857446caa 100644 --- a/wear/src/main/res/layout/action_editplusminus_item_quicklefty.xml +++ b/wear/src/main/res/layout/action_editplusminus_item_quicklefty.xml @@ -14,38 +14,11 @@ android:layout_marginEnd="-8dp" android:orientation="vertical"> - - - - - - + android:importantForAccessibility="no" + app:layout_constraintBottom_toTopOf="@+id/minus_button" + app:layout_constraintDimensionRatio="1:1" + app:layout_constraintLeft_toRightOf="@+id/plus_button3" + app:layout_constraintTop_toTopOf="@+id/plus_button3" /> diff --git a/wear/src/main/res/layout/action_editplusminus_item_quickrighty.xml b/wear/src/main/res/layout/action_editplusminus_item_quickrighty.xml index 7e3ae3dcb1..d2e7950a05 100644 --- a/wear/src/main/res/layout/action_editplusminus_item_quickrighty.xml +++ b/wear/src/main/res/layout/action_editplusminus_item_quickrighty.xml @@ -15,7 +15,7 @@ android:orientation="vertical"> - - - - + android:importantForAccessibility="no" - + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> Date: Tue, 28 Jun 2022 09:49:39 +0200 Subject: [PATCH 03/63] chore: align plus min item --- .../utils/EditPlusMinusViewAdapter.kt | 4 +- .../interaction/utils/PlusMinusEditText.kt | 6 +- .../res/layout/action_editplusminus_item.xml | 156 ++++++------------ .../layout/action_editplusminus_item_plus.xml | 13 +- .../action_editplusminus_item_quicklefty.xml | 2 +- ...ion_editplusminus_item_quicklefty_plus.xml | 33 ++-- .../action_editplusminus_item_quickrighty.xml | 2 +- ...on_editplusminus_item_quickrighty_plus.xml | 18 +- .../action_editplusminus_item_viktoria.xml | 6 +- 9 files changed, 86 insertions(+), 154 deletions(-) diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt index a1de3f1e9d..81c343db74 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt @@ -36,8 +36,8 @@ class EditPlusMinusViewAdapter( val editText = eD?.editText ?: eDP?.editText ?: eQL?.editText ?: eQLP?.editText ?: eQR?.editText ?: eQRP?.editText ?: eV?.editText ?: throw IllegalArgumentException("Missing require View Binding parameter display") - val minusButton = - eD?.minusButton ?: eDP?.minusButton ?: eQL?.minusButton ?: eQLP?.minusButton ?: eQR?.minusButton ?: eQRP?.minusButton ?: eV?.minusButton + val minButton = + eD?.minButton ?: eDP?.minButton ?: eQL?.minButton ?: eQLP?.minButton ?: eQR?.minButton ?: eQRP?.minButton ?: eV?.minButton ?: throw IllegalArgumentException("Missing require View Binding parameter display") val plusButton1 = eD?.plusButton1 ?: eDP?.plusButton1 ?: eQL?.plusButton1 ?: eQLP?.plusButton1 ?: eQR?.plusButton1 ?: eQRP?.plusButton1 ?: eV?.plusButton1 diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt index 2430c9e677..f3af7a89eb 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt @@ -253,9 +253,9 @@ import java.util.concurrent.TimeUnit editText.showSoftInputOnFocus = false editText.setTextIsSelectable(false) - binding.minusButton.setOnTouchListener(this) - binding.minusButton.setOnKeyListener(this) - binding.minusButton.setOnClickListener(this) + binding.minButton.setOnTouchListener(this) + binding.minButton.setOnKeyListener(this) + binding.minButton.setOnClickListener(this) binding.plusButton1.setOnTouchListener(this) binding.plusButton1.setOnKeyListener(this) binding.plusButton1.setOnClickListener(this) diff --git a/wear/src/main/res/layout/action_editplusminus_item.xml b/wear/src/main/res/layout/action_editplusminus_item.xml index 75c3b21594..5360d811dd 100644 --- a/wear/src/main/res/layout/action_editplusminus_item.xml +++ b/wear/src/main/res/layout/action_editplusminus_item.xml @@ -1,131 +1,67 @@ - - - - - - - + android:layout_height="match_parent" + android:layout_gravity="center" + android:gravity="center" + android:orientation="horizontal"> + android:tint="@color/white" /> - - - - - + android:orientation="vertical"> - + + + + + + android:tint="@color/white" /> - + diff --git a/wear/src/main/res/layout/action_editplusminus_item_plus.xml b/wear/src/main/res/layout/action_editplusminus_item_plus.xml index 18ea44cc13..2cbf3a620c 100644 --- a/wear/src/main/res/layout/action_editplusminus_item_plus.xml +++ b/wear/src/main/res/layout/action_editplusminus_item_plus.xml @@ -18,13 +18,13 @@ android:id="@+id/edit_text" android:layout_width="0dp" android:layout_height="wrap_content" - android:layout_marginTop="-6dp" android:layout_marginHorizontal="10dp" + android:layout_marginTop="-6dp" android:cursorVisible="false" + android:gravity="center" android:inputType="numberDecimal" android:textColor="@color/white" android:textSize="40sp" - android:gravity="center" app:layout_constraintEnd_toEndOf="@+id/value_background" app:layout_constraintStart_toStartOf="@+id/value_background" app:layout_constraintTop_toTopOf="@+id/value_background" @@ -34,8 +34,8 @@ android:id="@+id/label" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="-10dp" android:layout_below="@+id/edit_text" + android:layout_marginTop="-10dp" android:gravity="center" android:labelFor="@+id/edit_text" android:textColor="@color/white" @@ -47,7 +47,7 @@ tools:text="label" /> - @@ -89,26 +89,25 @@ android:textSize="30sp" app:layout_constraintBottom_toTopOf="@+id/plus_button1" app:layout_constraintCircle="@+id/center" - app:layout_constraintCircleAngle="270" - app:layout_constraintCircleRadius="65dp" + app:layout_constraintCircleAngle="90" + app:layout_constraintCircleRadius="70dp" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@+id/plus_button3" tools:text="+5" /> + app:layout_constraintBottom_toTopOf="@+id/min_button" + app:layout_constraintCircle="@+id/center" + app:layout_constraintCircleAngle="305" + app:layout_constraintCircleRadius="40dp" + app:layout_constraintRight_toLeftOf="@id/plus_button1" /> diff --git a/wear/src/main/res/layout/action_editplusminus_item_quickrighty.xml b/wear/src/main/res/layout/action_editplusminus_item_quickrighty.xml index d2e7950a05..16daa2e8c6 100644 --- a/wear/src/main/res/layout/action_editplusminus_item_quickrighty.xml +++ b/wear/src/main/res/layout/action_editplusminus_item_quickrighty.xml @@ -42,7 +42,7 @@ tools:text="label" /> + android:background="@drawable/circle" + android:backgroundTint="@color/gray_700" + android:contentDescription="@string/increment" + app:layout_constraintBottom_toTopOf="@+id/min_button" + app:layout_constraintCircle="@+id/center" + app:layout_constraintCircleAngle="305" + app:layout_constraintCircleRadius="40dp" + app:layout_constraintRight_toLeftOf="@id/plus_button1" /> + tools:text="label" /> - - From f0076ed0dd1fa3ce0c3242ebbc6be8b75be49d11 Mon Sep 17 00:00:00 2001 From: Andries Smit Date: Tue, 28 Jun 2022 10:06:05 +0200 Subject: [PATCH 04/63] chore: wear rename editplusmin layouts --- .../utils/EditPlusMinusViewAdapter.kt | 42 +++++++++---------- ...sminus_item.xml => action_editplusmin.xml} | 0 ..._plus.xml => action_editplusmin_multi.xml} | 0 ....xml => action_editplusmin_quicklefty.xml} | 0 ...> action_editplusmin_quicklefty_multi.xml} | 4 +- ...xml => action_editplusmin_quickrighty.xml} | 0 ... action_editplusmin_quickrighty_multi.xml} | 2 +- ...ia.xml => action_editplusmin_viktoria.xml} | 0 8 files changed, 24 insertions(+), 24 deletions(-) rename wear/src/main/res/layout/{action_editplusminus_item.xml => action_editplusmin.xml} (100%) rename wear/src/main/res/layout/{action_editplusminus_item_plus.xml => action_editplusmin_multi.xml} (100%) rename wear/src/main/res/layout/{action_editplusminus_item_quicklefty.xml => action_editplusmin_quicklefty.xml} (100%) rename wear/src/main/res/layout/{action_editplusminus_item_quicklefty_plus.xml => action_editplusmin_quicklefty_multi.xml} (98%) rename wear/src/main/res/layout/{action_editplusminus_item_quickrighty.xml => action_editplusmin_quickrighty.xml} (100%) rename wear/src/main/res/layout/{action_editplusminus_item_quickrighty_plus.xml => action_editplusmin_quickrighty_multi.xml} (99%) rename wear/src/main/res/layout/{action_editplusminus_item_viktoria.xml => action_editplusmin_viktoria.xml} (100%) diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt index 81c343db74..df13d69b8a 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt @@ -4,13 +4,13 @@ import android.content.Context import android.view.LayoutInflater import android.view.ViewGroup import info.nightscout.androidaps.R -import info.nightscout.androidaps.databinding.ActionEditplusminusItemBinding -import info.nightscout.androidaps.databinding.ActionEditplusminusItemPlusBinding -import info.nightscout.androidaps.databinding.ActionEditplusminusItemQuickleftyPlusBinding -import info.nightscout.androidaps.databinding.ActionEditplusminusItemQuickleftyBinding -import info.nightscout.androidaps.databinding.ActionEditplusminusItemQuickrightyBinding -import info.nightscout.androidaps.databinding.ActionEditplusminusItemQuickrightyPlusBinding -import info.nightscout.androidaps.databinding.ActionEditplusminusItemViktoriaBinding +import info.nightscout.androidaps.databinding.ActionEditplusminBinding +import info.nightscout.androidaps.databinding.ActionEditplusminMultiBinding +import info.nightscout.androidaps.databinding.ActionEditplusminQuickleftyMultiBinding +import info.nightscout.androidaps.databinding.ActionEditplusminQuickleftyBinding +import info.nightscout.androidaps.databinding.ActionEditplusminQuickrightyBinding +import info.nightscout.androidaps.databinding.ActionEditplusminQuickrightyMultiBinding +import info.nightscout.androidaps.databinding.ActionEditplusminViktoriaBinding import info.nightscout.shared.sharedPreferences.SP /** @@ -18,13 +18,13 @@ import info.nightscout.shared.sharedPreferences.SP * Requires at least one of the ViewBinding as a parameter. Recommended to use the factory object to create the binding. */ class EditPlusMinusViewAdapter( - eD: ActionEditplusminusItemBinding?, - eDP: ActionEditplusminusItemPlusBinding?, - eQL: ActionEditplusminusItemQuickleftyBinding?, - eQLP: ActionEditplusminusItemQuickleftyPlusBinding?, - eQR: ActionEditplusminusItemQuickrightyBinding?, - eQRP: ActionEditplusminusItemQuickrightyPlusBinding?, - eV: ActionEditplusminusItemViktoriaBinding? + eD: ActionEditplusminBinding?, + eDP: ActionEditplusminMultiBinding?, + eQL: ActionEditplusminQuickleftyBinding?, + eQLP: ActionEditplusminQuickleftyMultiBinding?, + eQR: ActionEditplusminQuickrightyBinding?, + eQRP: ActionEditplusminQuickrightyMultiBinding?, + eV: ActionEditplusminViktoriaBinding? ) { init { @@ -59,35 +59,35 @@ class EditPlusMinusViewAdapter( return when (sp.getInt(R.string.key_input_design, 1)) { 2 -> { if (multiple) { - val bindLayout = ActionEditplusminusItemQuickrightyPlusBinding.inflate(inflater, container, false) + val bindLayout = ActionEditplusminQuickrightyMultiBinding.inflate(inflater, container, false) EditPlusMinusViewAdapter(null, null, null, null, null, bindLayout, null) } else { - val bindLayout = ActionEditplusminusItemQuickrightyBinding.inflate(inflater, container, false) + val bindLayout = ActionEditplusminQuickrightyBinding.inflate(inflater, container, false) EditPlusMinusViewAdapter(null, null, null, null, bindLayout, null, null) } } 3 -> { if (multiple) { - val bindLayout = ActionEditplusminusItemQuickleftyPlusBinding.inflate(inflater, container, false) + val bindLayout = ActionEditplusminQuickleftyMultiBinding.inflate(inflater, container, false) EditPlusMinusViewAdapter(null, null, null, bindLayout, null, null, null) } else { - val bindLayout = ActionEditplusminusItemQuickleftyBinding.inflate(inflater, container, false) + val bindLayout = ActionEditplusminQuickleftyBinding.inflate(inflater, container, false) EditPlusMinusViewAdapter(null, null, bindLayout, null, null, null, null) } } 4 -> { - val bindLayout = ActionEditplusminusItemViktoriaBinding.inflate(inflater, container, false) + val bindLayout = ActionEditplusminViktoriaBinding.inflate(inflater, container, false) EditPlusMinusViewAdapter(null, null, null, null, null, null, bindLayout) } else -> { if (multiple) { - val bindLayout = ActionEditplusminusItemPlusBinding.inflate(inflater, container, false) + val bindLayout = ActionEditplusminMultiBinding.inflate(inflater, container, false) EditPlusMinusViewAdapter(null, bindLayout, null, null, null, null, null) } else { - val bindLayout = ActionEditplusminusItemBinding.inflate(inflater, container, false) + val bindLayout = ActionEditplusminBinding.inflate(inflater, container, false) EditPlusMinusViewAdapter(bindLayout, null, null, null, null, null, null) } } diff --git a/wear/src/main/res/layout/action_editplusminus_item.xml b/wear/src/main/res/layout/action_editplusmin.xml similarity index 100% rename from wear/src/main/res/layout/action_editplusminus_item.xml rename to wear/src/main/res/layout/action_editplusmin.xml diff --git a/wear/src/main/res/layout/action_editplusminus_item_plus.xml b/wear/src/main/res/layout/action_editplusmin_multi.xml similarity index 100% rename from wear/src/main/res/layout/action_editplusminus_item_plus.xml rename to wear/src/main/res/layout/action_editplusmin_multi.xml diff --git a/wear/src/main/res/layout/action_editplusminus_item_quicklefty.xml b/wear/src/main/res/layout/action_editplusmin_quicklefty.xml similarity index 100% rename from wear/src/main/res/layout/action_editplusminus_item_quicklefty.xml rename to wear/src/main/res/layout/action_editplusmin_quicklefty.xml diff --git a/wear/src/main/res/layout/action_editplusminus_item_quicklefty_plus.xml b/wear/src/main/res/layout/action_editplusmin_quicklefty_multi.xml similarity index 98% rename from wear/src/main/res/layout/action_editplusminus_item_quicklefty_plus.xml rename to wear/src/main/res/layout/action_editplusmin_quicklefty_multi.xml index 121be927ac..5a4e9b10cb 100644 --- a/wear/src/main/res/layout/action_editplusminus_item_quicklefty_plus.xml +++ b/wear/src/main/res/layout/action_editplusmin_quicklefty_multi.xml @@ -35,7 +35,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/edit_text" - android:layout_marginTop="-8dp" + android:layout_marginTop="-9dp" android:gravity="center" android:labelFor="@+id/edit_text" android:textColor="@color/white" @@ -44,7 +44,7 @@ app:layout_constraintStart_toStartOf="@+id/edit_text" app:layout_constraintTop_toBottomOf="@id/edit_text" tools:ignore="LabelFor" - tools:text="label" /> + tools:text="label123" /> Date: Tue, 28 Jun 2022 10:58:45 +0200 Subject: [PATCH 05/63] chore: fix code smells --- .../wear/wearintegration/DataHandlerMobile.kt | 8 ++++---- .../info/nightscout/shared/weardata/EventData.kt | 8 ++++---- .../androidaps/comm/DataHandlerWear.kt | 8 ++++---- .../interaction/actions/TempTargetActivity.kt | 1 - .../utils/EditPlusMinusViewAdapter.kt | 16 ++++++++-------- .../interaction/utils/PlusMinusEditText.kt | 7 ++----- 6 files changed, 22 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt index 25017bfa3b..4ddbd962cd 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/DataHandlerMobile.kt @@ -697,10 +697,10 @@ class DataHandlerMobile @Inject constructor( bolusPercentage = sp.getInt(R.string.key_boluswizard_percentage, 100), maxCarbs = sp.getInt(R.string.key_treatmentssafety_maxcarbs, 48), maxBolus = sp.getDouble(R.string.key_treatmentssafety_maxbolus, 3.0), - insulin_button_increment_1 = sp.getDouble(R.string.key_insulin_button_increment_1, InsulinDialog.PLUS1_DEFAULT), - insulin_button_increment_2 = sp.getDouble(R.string.key_insulin_button_increment_2, InsulinDialog.PLUS2_DEFAULT), - carbs_button_increment_1 = sp.getInt(R.string.key_carbs_button_increment_1, CarbsDialog.FAV1_DEFAULT), - carbs_button_increment_2 = sp.getInt(R.string.key_carbs_button_increment_2, CarbsDialog.FAV2_DEFAULT) + insulinButtonIncrement1 = sp.getDouble(R.string.key_insulin_button_increment_1, InsulinDialog.PLUS1_DEFAULT), + insulinButtonIncrement2 = sp.getDouble(R.string.key_insulin_button_increment_2, InsulinDialog.PLUS2_DEFAULT), + carbsButtonIncrement1 = sp.getInt(R.string.key_carbs_button_increment_1, CarbsDialog.FAV1_DEFAULT), + carbsButtonIncrement2 = sp.getInt(R.string.key_carbs_button_increment_2, CarbsDialog.FAV2_DEFAULT) ) ) ) diff --git a/shared/src/main/java/info/nightscout/shared/weardata/EventData.kt b/shared/src/main/java/info/nightscout/shared/weardata/EventData.kt index bd0d06711b..b0fe71d4aa 100644 --- a/shared/src/main/java/info/nightscout/shared/weardata/EventData.kt +++ b/shared/src/main/java/info/nightscout/shared/weardata/EventData.kt @@ -209,10 +209,10 @@ sealed class EventData : Event() { val bolusPercentage: Int, val maxCarbs: Int, val maxBolus: Double, - val insulin_button_increment_1: Double, - val insulin_button_increment_2: Double, - val carbs_button_increment_1: Int, - val carbs_button_increment_2: Int + val insulinButtonIncrement1: Double, + val insulinButtonIncrement2: Double, + val carbsButtonIncrement1: Int, + val carbsButtonIncrement2: Int ) : EventData() @Serializable diff --git a/wear/src/main/java/info/nightscout/androidaps/comm/DataHandlerWear.kt b/wear/src/main/java/info/nightscout/androidaps/comm/DataHandlerWear.kt index 3a05c06cf0..321ccefeeb 100644 --- a/wear/src/main/java/info/nightscout/androidaps/comm/DataHandlerWear.kt +++ b/wear/src/main/java/info/nightscout/androidaps/comm/DataHandlerWear.kt @@ -162,10 +162,10 @@ class DataHandlerWear @Inject constructor( sp.putInt(R.string.key_bolus_wizard_percentage, it.bolusPercentage) sp.putInt(R.string.key_treatments_safety_max_carbs, it.maxCarbs) sp.putDouble(R.string.key_treatments_safety_max_bolus, it.maxBolus) - sp.putDouble(R.string.key_insulin_button_increment_1, it.insulin_button_increment_1) - sp.putDouble(R.string.key_insulin_button_increment_2, it.insulin_button_increment_2) - sp.putInt(R.string.key_carbs_button_increment_1, it.carbs_button_increment_1) - sp.putInt(R.string.key_carbs_button_increment_2, it.carbs_button_increment_2) + sp.putDouble(R.string.key_insulin_button_increment_1, it.insulinButtonIncrement1) + sp.putDouble(R.string.key_insulin_button_increment_2, it.insulinButtonIncrement2) + sp.putInt(R.string.key_carbs_button_increment_1, it.carbsButtonIncrement1) + sp.putInt(R.string.key_carbs_button_increment_2, it.carbsButtonIncrement2) } disposable += rxBus .toObservable(EventData.QuickWizard::class.java) diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TempTargetActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TempTargetActivity.kt index 26570a6bdd..80180d850a 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TempTargetActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TempTargetActivity.kt @@ -74,7 +74,6 @@ class TempTargetActivity : ViewSelectorActivity() { if (lowRange != null) def = SafeParse.stringToDouble(lowRange?.editText?.text.toString()) lowRange = PlusMinusEditText(viewAdapter, def, 4.0, 10.0, 0.1, DecimalFormat("#0.0"), false, title) } - container.addView(view) view } diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt index df13d69b8a..4bb22f95e4 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/EditPlusMinusViewAdapter.kt @@ -14,7 +14,7 @@ import info.nightscout.androidaps.databinding.ActionEditplusminViktoriaBinding import info.nightscout.shared.sharedPreferences.SP /** - * EditPlusMinusViewAdapter binds both ActionEditplusminusItemBinding variants shared attributes to one common view adapter. + * EditPlusMinusViewAdapter binds both ActionEditplusminBinding variants shared attributes to one common view adapter. * Requires at least one of the ViewBinding as a parameter. Recommended to use the factory object to create the binding. */ class EditPlusMinusViewAdapter( @@ -32,28 +32,28 @@ class EditPlusMinusViewAdapter( throw IllegalArgumentException("Require at least on Binding parameter") } } - + private val errorMessage = "Missing require View Binding parameter" val editText = eD?.editText ?: eDP?.editText ?: eQL?.editText ?: eQLP?.editText ?: eQR?.editText ?: eQRP?.editText ?: eV?.editText - ?: throw IllegalArgumentException("Missing require View Binding parameter display") + ?: throw IllegalArgumentException(errorMessage) val minButton = eD?.minButton ?: eDP?.minButton ?: eQL?.minButton ?: eQLP?.minButton ?: eQR?.minButton ?: eQRP?.minButton ?: eV?.minButton - ?: throw IllegalArgumentException("Missing require View Binding parameter display") + ?: throw IllegalArgumentException(errorMessage) val plusButton1 = eD?.plusButton1 ?: eDP?.plusButton1 ?: eQL?.plusButton1 ?: eQLP?.plusButton1 ?: eQR?.plusButton1 ?: eQRP?.plusButton1 ?: eV?.plusButton1 - ?: throw IllegalArgumentException("Missing require View Binding parameter display") + ?: throw IllegalArgumentException(errorMessage) val label = eD?.label ?: eDP?.label ?: eQL?.label ?: eQLP?.label ?: eQR?.label ?: eQRP?.label ?: eV?.label - ?: throw IllegalArgumentException("Missing require View Binding parameter display") + ?: throw IllegalArgumentException(errorMessage) val plusButton2 = eDP?.plusButton2 ?: eQLP?.plusButton2 ?: eQRP?.plusButton2 val plusButton3 = eDP?.plusButton3 ?: eQLP?.plusButton3 ?: eQRP?.plusButton3 val root = eD?.root ?: eDP?.root ?: eQL?.root ?: eQLP?.root ?: eQR?.root ?: eQRP?.root ?: eV?.root - ?: throw IllegalArgumentException("Missing require View Binding parameter display") + ?: throw IllegalArgumentException(errorMessage) companion object { - fun getViewAdapter(sp: SP, context: Context, container: ViewGroup?, multiple: Boolean = false): EditPlusMinusViewAdapter { + fun getViewAdapter(sp: SP, context: Context, container: ViewGroup, multiple: Boolean = false): EditPlusMinusViewAdapter { val inflater = LayoutInflater.from(context) return when (sp.getInt(R.string.key_input_design, 1)) { diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt index f3af7a89eb..d6933c1a13 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/utils/PlusMinusEditText.kt @@ -1,6 +1,5 @@ package info.nightscout.androidaps.interaction.utils -import android.annotation.SuppressLint import android.content.Context import android.os.* import android.view.KeyEvent @@ -20,7 +19,7 @@ import java.util.concurrent.TimeUnit /** * Created by mike on 28.06.2016. */ -@SuppressLint("SetTextI18n") class PlusMinusEditText @JvmOverloads constructor( +class PlusMinusEditText @JvmOverloads constructor( private val binding: EditPlusMinusViewAdapter, initValue: Double, private val minValue: Double, @@ -106,9 +105,7 @@ import java.util.concurrent.TimeUnit private fun vibrateDevice() { val vibrator = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { - val vibratorManager = - binding.root.context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager - vibratorManager.defaultVibrator + (binding.root.context.getSystemService(Context.VIBRATOR_MANAGER_SERVICE) as VibratorManager).defaultVibrator } else { @Suppress("DEPRECATION") binding.root.context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator From 6f6b16805632b1b286948e447c2be06a4bbbb79d Mon Sep 17 00:00:00 2001 From: Andries Smit Date: Thu, 30 Jun 2022 08:53:42 +0200 Subject: [PATCH 06/63] chore: wear remove bg multi plus --- .../interaction/actions/ECarbActivity.kt | 3 +-- .../interaction/actions/FillActivity.kt | 2 +- .../actions/ProfileSwitchActivity.kt | 2 +- .../interaction/actions/TempTargetActivity.kt | 2 +- .../interaction/actions/TreatmentActivity.kt | 2 +- .../action_editplusmin_quicklefty_multi.xml | 24 ++++++++----------- .../action_editplusmin_quickrighty_multi.xml | 9 ++----- 7 files changed, 17 insertions(+), 27 deletions(-) diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ECarbActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ECarbActivity.kt index 0a643e9bff..919d92b1dd 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ECarbActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ECarbActivity.kt @@ -84,8 +84,7 @@ class ECarbActivity : ViewSelectorActivity() { val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) val confirmButton = view.findViewById(R.id.confirmbutton) confirmButton.setOnClickListener { - - //check if it can happen that the fragment is never created that hold data? + // check if it can happen that the fragment is never created that hold data? // (you have to swipe past them anyways - but still) val bolus = ActionECarbsPreCheck( stringToInt(editCarbs?.editText?.text.toString()), diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/FillActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/FillActivity.kt index 2525033df0..9fdfa97d26 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/FillActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/FillActivity.kt @@ -52,7 +52,7 @@ class FillActivity : ViewSelectorActivity() { val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) val confirmButton = view.findViewById(R.id.confirmbutton) confirmButton.setOnClickListener { - //check if it can happen that the fragment is never created that hold data? + // check if it can happen that the fragment is never created that hold data? // (you have to swipe past them anyways - but still) rxBus.send(EventWearToMobile(ActionFillPreCheck(stringToDouble(editInsulin?.editText?.text.toString())))) showToast(this@FillActivity, R.string.action_fill_confirmation) diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ProfileSwitchActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ProfileSwitchActivity.kt index c6498f2638..8aa2a26437 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ProfileSwitchActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/ProfileSwitchActivity.kt @@ -75,7 +75,7 @@ class ProfileSwitchActivity : ViewSelectorActivity() { val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) val confirmButton = view.findViewById(R.id.confirmbutton) confirmButton.setOnClickListener { - //check if it can happen that the fragment is never created that hold data? + // check if it can happen that the fragment is never created that hold data? // (you have to swipe past them anyways - but still) val ps = ActionProfileSwitchPreCheck(SafeParse.stringToInt(editTimeshift?.editText?.text.toString()), SafeParse.stringToInt(editPercentage?.editText?.text.toString())) rxBus.send(EventWearToMobile(ps)) diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TempTargetActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TempTargetActivity.kt index 80180d850a..77f1c256dc 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TempTargetActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TempTargetActivity.kt @@ -98,7 +98,7 @@ class TempTargetActivity : ViewSelectorActivity() { val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) val confirmButton = view.findViewById(R.id.confirmbutton) confirmButton.setOnClickListener { - //check if it can happen that the fragment is never created that hold data? + // check if it can happen that the fragment is never created that hold data? // (you have to swipe past them anyways - but still) val action = ActionTempTargetPreCheck( ActionTempTargetPreCheck.TempTargetCommand.MANUAL, diff --git a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TreatmentActivity.kt b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TreatmentActivity.kt index 55805803d4..1cb7c36879 100644 --- a/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TreatmentActivity.kt +++ b/wear/src/main/java/info/nightscout/androidaps/interaction/actions/TreatmentActivity.kt @@ -73,7 +73,7 @@ class TreatmentActivity : ViewSelectorActivity() { val view = LayoutInflater.from(applicationContext).inflate(R.layout.action_confirm_ok, container, false) val confirmButton = view.findViewById(R.id.confirmbutton) confirmButton.setOnClickListener { - //check if it can happen that the fragment is never created that hold data? + // check if it can happen that the fragment is never created that hold data? // (you have to swipe past them anyways - but still) val bolus = ActionBolusPreCheck(stringToDouble(editInsulin?.editText?.text.toString()), stringToInt(editCarbs?.editText?.text.toString())) rxBus.send(EventWearToMobile(bolus)) diff --git a/wear/src/main/res/layout/action_editplusmin_quicklefty_multi.xml b/wear/src/main/res/layout/action_editplusmin_quicklefty_multi.xml index 5a4e9b10cb..d5acf0460d 100644 --- a/wear/src/main/res/layout/action_editplusmin_quicklefty_multi.xml +++ b/wear/src/main/res/layout/action_editplusmin_quicklefty_multi.xml @@ -19,7 +19,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginHorizontal="10dp" - android:layout_marginTop="-10dp" + android:layout_marginTop="-5dp" android:cursorVisible="false" android:gravity="center" android:inputType="numberDecimal" @@ -44,7 +44,7 @@ app:layout_constraintStart_toStartOf="@+id/edit_text" app:layout_constraintTop_toBottomOf="@id/edit_text" tools:ignore="LabelFor" - tools:text="label123" /> + tools:text="label" /> @@ -72,7 +72,7 @@ android:textSize="25sp" android:visibility="visible" app:layout_constraintCircle="@+id/center" - app:layout_constraintCircleAngle="35" + app:layout_constraintCircleAngle="325" app:layout_constraintCircleRadius="70dp" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" @@ -89,25 +89,21 @@ android:textSize="30sp" app:layout_constraintBottom_toTopOf="@+id/plus_button1" app:layout_constraintCircle="@+id/center" - app:layout_constraintCircleAngle="90" + app:layout_constraintCircleAngle="270" app:layout_constraintCircleRadius="70dp" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toBottomOf="@+id/plus_button3" tools:text="+5" /> - + app:layout_constraintLeft_toRightOf="@id/plus_button3" /> diff --git a/wear/src/main/res/layout/action_editplusmin_quickrighty_multi.xml b/wear/src/main/res/layout/action_editplusmin_quickrighty_multi.xml index 93840e6869..0cd6b4f344 100644 --- a/wear/src/main/res/layout/action_editplusmin_quickrighty_multi.xml +++ b/wear/src/main/res/layout/action_editplusmin_quickrighty_multi.xml @@ -19,7 +19,7 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginHorizontal="10dp" - android:layout_marginTop="-1dp" + android:layout_marginTop="-5dp" android:cursorVisible="false" android:gravity="center" android:inputType="numberDecimal" @@ -95,15 +95,10 @@ app:layout_constraintTop_toBottomOf="@+id/plus_button3" tools:text="+5" /> - Date: Thu, 30 Jun 2022 08:10:07 +0000 Subject: [PATCH 07/63] Bump lifecycle-livedata-ktx from 2.4.1 to 2.5.0 Bumps lifecycle-livedata-ktx from 2.4.1 to 2.5.0. --- updated-dependencies: - dependency-name: androidx.lifecycle:lifecycle-livedata-ktx dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f4ac0a131f..0f1228a852 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ buildscript { rxandroid_version = '3.0.0' rxkotlin_version = '3.0.1' room_version = '2.4.2' - lifecycle_version = '2.4.1' + lifecycle_version = '2.5.0' dagger_version = '2.42' coroutines_version = '1.6.3' activity_version = '1.4.0' From e83d10d856aeccdeeeb62db707aeaad45d3a67f1 Mon Sep 17 00:00:00 2001 From: Andries Smit Date: Thu, 30 Jun 2022 20:29:04 +0200 Subject: [PATCH 08/63] chore: wear plus min center label min button --- .../main/res/layout/action_editplusmin_quicklefty_multi.xml | 6 ++---- .../res/layout/action_editplusmin_quickrighty_multi.xml | 6 ++---- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/wear/src/main/res/layout/action_editplusmin_quicklefty_multi.xml b/wear/src/main/res/layout/action_editplusmin_quicklefty_multi.xml index d5acf0460d..044232b032 100644 --- a/wear/src/main/res/layout/action_editplusmin_quicklefty_multi.xml +++ b/wear/src/main/res/layout/action_editplusmin_quicklefty_multi.xml @@ -100,10 +100,8 @@ android:layout_width="108dp" android:layout_height="108dp" app:layout_constraintBottom_toTopOf="@+id/min_button" - app:layout_constraintCircle="@+id/center" - app:layout_constraintCircleAngle="55" - app:layout_constraintCircleRadius="40dp" - app:layout_constraintLeft_toRightOf="@id/plus_button3" /> + app:layout_constraintLeft_toLeftOf="@+id/min_button" + app:layout_constraintRight_toRightOf="@+id/min_button"/> + app:layout_constraintRight_toRightOf="@id/min_button" + app:layout_constraintLeft_toLeftOf="@id/min_button"/> Date: Thu, 30 Jun 2022 23:44:32 +0200 Subject: [PATCH 09/63] MDT: fix initialization --- .../pump/medtronic/MedtronicFragment.kt | 42 +++++++++---------- .../pump/medtronic/MedtronicPumpPlugin.kt | 29 ++++--------- .../service/RileyLinkBroadcastReceiver.kt | 5 +-- .../hw/rileylink/service/RileyLinkService.kt | 2 +- .../service/RileyLinkServiceData.java | 6 +-- 5 files changed, 34 insertions(+), 50 deletions(-) diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt index e3e0642a70..d65509810f 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt @@ -2,7 +2,6 @@ package info.nightscout.androidaps.plugins.pump.medtronic import android.annotation.SuppressLint import android.content.Intent -import android.graphics.Color import android.os.Bundle import android.os.Handler import android.os.HandlerThread @@ -16,13 +15,11 @@ import info.nightscout.androidaps.events.EventTempBasalChange import info.nightscout.androidaps.interfaces.ActivePlugin import info.nightscout.androidaps.interfaces.CommandQueue import info.nightscout.androidaps.interfaces.PumpSync -import info.nightscout.shared.logging.AAPSLogger -import info.nightscout.shared.logging.LTag +import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.pump.common.defs.PumpDeviceState import info.nightscout.androidaps.plugins.pump.common.events.EventRefreshButtonState import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyLinkStatusActivity @@ -42,8 +39,9 @@ import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.WarnColors import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers +import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.logging.LTag import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign import javax.inject.Inject @@ -59,7 +57,6 @@ class MedtronicFragment : DaggerFragment() { @Inject lateinit var activePlugin: ActivePlugin @Inject lateinit var medtronicPumpPlugin: MedtronicPumpPlugin @Inject lateinit var warnColors: WarnColors - @Inject lateinit var rileyLinkUtil: RileyLinkUtil @Inject lateinit var medtronicUtil: MedtronicUtil @Inject lateinit var medtronicPumpStatus: MedtronicPumpStatus @Inject lateinit var rileyLinkServiceData: RileyLinkServiceData @@ -92,7 +89,7 @@ class MedtronicFragment : DaggerFragment() { binding.rlStatus.text = rh.gs(RileyLinkServiceState.NotStarted.resourceId) - binding.pumpStatusIcon.setTextColor(rh.gac(context,R.attr.defaultTextColor)) + binding.pumpStatusIcon.setTextColor(rh.gac(context, R.attr.defaultTextColor)) @SuppressLint("SetTextI18n") binding.pumpStatusIcon.text = "{fa-bed}" @@ -139,9 +136,9 @@ class MedtronicFragment : DaggerFragment() { .toObservable(EventRileyLinkDeviceStatusChange::class.java) .observeOn(aapsSchedulers.main) .subscribe({ - aapsLogger.debug(LTag.PUMP, "onStatusEvent(EventRileyLinkDeviceStatusChange): $it") - setDeviceStatus() - }, fabricPrivacy::logException) + aapsLogger.debug(LTag.PUMP, "onStatusEvent(EventRileyLinkDeviceStatusChange): $it") + setDeviceStatus() + }, fabricPrivacy::logException) disposable += rxBus .toObservable(EventMedtronicPumpValuesChanged::class.java) .observeOn(aapsSchedulers.main) @@ -158,10 +155,10 @@ class MedtronicFragment : DaggerFragment() { .toObservable(EventMedtronicPumpConfigurationChanged::class.java) .observeOn(aapsSchedulers.main) .subscribe({ - aapsLogger.debug(LTag.PUMP, "EventMedtronicPumpConfigurationChanged triggered") - medtronicPumpPlugin.rileyLinkService?.verifyConfiguration() - updateGUI() - }, fabricPrivacy::logException) + aapsLogger.debug(LTag.PUMP, "EventMedtronicPumpConfigurationChanged triggered") + medtronicPumpPlugin.rileyLinkService?.verifyConfiguration() + updateGUI() + }, fabricPrivacy::logException) disposable += rxBus .toObservable(EventPumpStatusChanged::class.java) .observeOn(aapsSchedulers.main) @@ -200,7 +197,7 @@ class MedtronicFragment : DaggerFragment() { rileyLinkServiceData.rileyLinkServiceState.isError && rileyLinkError != null -> "{fa-bluetooth-b} " + rh.gs(rileyLinkError.getResourceId(RileyLinkTargetDevice.MedtronicPump)) else -> "{fa-bluetooth-b} " + rh.gs(resourceId) } - binding.rlStatus.setTextColor(rh.gac( context, if (rileyLinkError != null) R.attr.warningColor else R.attr.defaultTextColor)) + binding.rlStatus.setTextColor(rh.gac(context, if (rileyLinkError != null) R.attr.warningColor else R.attr.defaultTextColor)) binding.errors.text = rileyLinkServiceData.rileyLinkError?.let { @@ -253,8 +250,10 @@ class MedtronicFragment : DaggerFragment() { private fun displayNotConfiguredDialog() { context?.let { - OKDialog.show(it, rh.gs(R.string.medtronic_warning), - rh.gs(R.string.medtronic_error_operation_not_possible_no_configuration), null) + OKDialog.show( + it, rh.gs(R.string.medtronic_warning), + rh.gs(R.string.medtronic_error_operation_not_possible_no_configuration), null + ) } } @@ -272,7 +271,7 @@ class MedtronicFragment : DaggerFragment() { val min = (System.currentTimeMillis() - medtronicPumpStatus.lastConnection) / 1000 / 60 if (medtronicPumpStatus.lastConnection + 60 * 1000 > System.currentTimeMillis()) { binding.lastConnection.setText(R.string.medtronic_pump_connected_now) - binding.lastConnection.setTextColor(rh.gac(context,R.attr.defaultTextColor)) + binding.lastConnection.setTextColor(rh.gac(context, R.attr.defaultTextColor)) } else if (medtronicPumpStatus.lastConnection + 30 * 60 * 1000 < System.currentTimeMillis()) { if (min < 60) { @@ -288,10 +287,10 @@ class MedtronicFragment : DaggerFragment() { binding.lastConnection.text = (rh.gq(R.plurals.duration_days, d, d) + " " + rh.gs(R.string.ago)) } - binding.lastConnection.setTextColor(rh.gac(context,R.attr.warningColor)) + binding.lastConnection.setTextColor(rh.gac(context, R.attr.warningColor)) } else { binding.lastConnection.text = minAgo - binding.lastConnection.setTextColor(rh.gac(context,R.attr.defaultTextColor)) + binding.lastConnection.setTextColor(rh.gac(context, R.attr.defaultTextColor)) } } @@ -329,7 +328,8 @@ class MedtronicFragment : DaggerFragment() { if (medtronicPumpStatus.batteryType == BatteryType.None || medtronicPumpStatus.batteryVoltage == null) { binding.pumpStateBattery.text = "{fa-battery-" + medtronicPumpStatus.batteryRemaining / 25 + "} " } else { - binding.pumpStateBattery.text = "{fa-battery-" + medtronicPumpStatus.batteryRemaining / 25 + "} " + medtronicPumpStatus.batteryRemaining + "%" + String.format(" (%.2f V)", medtronicPumpStatus.batteryVoltage) + binding.pumpStateBattery.text = + "{fa-battery-" + medtronicPumpStatus.batteryRemaining / 25 + "} " + medtronicPumpStatus.batteryRemaining + "%" + String.format(" (%.2f V)", medtronicPumpStatus.batteryVoltage) } warnColors.setColorInverse(binding.pumpStateBattery, medtronicPumpStatus.batteryRemaining.toDouble(), 25.0, 10.0) diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt index 2fbebf5bf7..01ff035702 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt @@ -55,6 +55,7 @@ import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.TimeChangeType import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag @@ -215,27 +216,13 @@ class MedtronicPumpPlugin @Inject constructor( }.start() } - override val serviceClass: Class<*> - get() = RileyLinkMedtronicService::class.java - - override val pumpStatusData: info.nightscout.androidaps.plugins.pump.common.data.PumpStatus - get() = medtronicPumpStatus - - override fun deviceID(): String { - return "Medtronic" - } - - override val isFakingTempsByExtendedBoluses: Boolean - get() = false - - override fun canHandleDST(): Boolean { - return false - } - - // Pump Plugin + override val serviceClass: Class<*> = RileyLinkMedtronicService::class.java + override val pumpStatusData: PumpStatus get() = medtronicPumpStatus + override fun deviceID(): String = "Medtronic" + override val isFakingTempsByExtendedBoluses: Boolean = false + override fun canHandleDST(): Boolean = false private var isServiceSet: Boolean = false - - override val rileyLinkService: RileyLinkMedtronicService? = rileyLinkMedtronicService + override val rileyLinkService: RileyLinkMedtronicService? get() = rileyLinkMedtronicService override val pumpInfo: RileyLinkPumpInfo get() = RileyLinkPumpInfo( @@ -244,7 +231,7 @@ class MedtronicPumpPlugin @Inject constructor( medtronicPumpStatus.serialNumber ) - override val lastConnectionTimeMillis: Long = medtronicPumpStatus.lastConnection + override val lastConnectionTimeMillis: Long get() = medtronicPumpStatus.lastConnection override fun setLastCommunicationToNow() { medtronicPumpStatus.setLastCommunicationToNow() diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.kt b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.kt index bfbaf4b184..1fb2ca414c 100644 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.kt +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.kt @@ -120,9 +120,8 @@ class RileyLinkBroadcastReceiver : DaggerBroadcastReceiver() { RileyLinkConst.Intents.RileyLinkNewAddressSet -> { val rileylinkBLEAddress = sp.getString(RileyLinkConst.Prefs.RileyLinkAddress, "") - if (rileylinkBLEAddress == "") { - aapsLogger.error("No Rileylink BLE Address saved in app") - } else rileyLinkService?.reconfigureRileyLink(rileylinkBLEAddress) + if (rileylinkBLEAddress == "") aapsLogger.error("No Rileylink BLE Address saved in app") + else rileyLinkService?.reconfigureRileyLink(rileylinkBLEAddress) true } diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkService.kt b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkService.kt index 47449c5c3f..d7503bf2a6 100644 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkService.kt +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkService.kt @@ -44,7 +44,7 @@ abstract class RileyLinkService : DaggerService() { @Inject lateinit var rfSpy: RFSpy // interface for RL xxx Mhz radio. private val bluetoothAdapter: BluetoothAdapter? get() = (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter - protected var broadcastReceiver: RileyLinkBroadcastReceiver? = null + private var broadcastReceiver: RileyLinkBroadcastReceiver? = null private var bluetoothStateReceiver: RileyLinkBluetoothStateReceiver? = null override fun onCreate() { diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.java b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.java index 64cca36a50..e6f3f30889 100644 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.java +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.java @@ -6,9 +6,6 @@ import javax.annotation.Nullable; import javax.inject.Inject; import javax.inject.Singleton; -import info.nightscout.androidaps.interfaces.ActivePlugin; -import info.nightscout.shared.logging.AAPSLogger; -import info.nightscout.shared.logging.LTag; import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; @@ -18,6 +15,8 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistor import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice; +import info.nightscout.shared.logging.AAPSLogger; +import info.nightscout.shared.logging.LTag; /** * Created by andy on 16/05/2018. @@ -30,7 +29,6 @@ public class RileyLinkServiceData { @Inject AAPSLogger aapsLogger; @Inject RileyLinkUtil rileyLinkUtil; @Inject RxBus rxBus; - @Inject ActivePlugin activePlugin; boolean tuneUpDone = false; public RileyLinkError rileyLinkError; From 23bdb57ed318699769b7fe5dd8ce9ea613661181 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 1 Jul 2022 00:07:38 +0200 Subject: [PATCH 10/63] RileyLinkServiceData resolve nullability --- .../pump/medtronic/MedtronicFragment.kt | 12 ++++-------- .../service/RileyLinkBroadcastReceiver.kt | 2 +- .../service/RileyLinkServiceData.java | 18 +++++++++--------- .../service/tasks/InitializePumpManagerTask.kt | 3 +-- 4 files changed, 15 insertions(+), 20 deletions(-) diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt index d65509810f..86666790a5 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt @@ -340,19 +340,15 @@ class MedtronicFragment : DaggerFragment() { medtronicPumpPlugin.rileyLinkService?.verifyConfiguration() binding.errors.text = medtronicPumpStatus.errorInfo - val showRileyLinkBatteryLevel: Boolean = rileyLinkServiceData.showBatteryLevel - - if (showRileyLinkBatteryLevel) { + if (rileyLinkServiceData.showBatteryLevel) { binding.rlBatteryView.visibility = View.VISIBLE binding.rlBatteryLabel.visibility = View.VISIBLE binding.rlBatteryState.visibility = View.VISIBLE binding.rlBatteryLayout.visibility = View.VISIBLE binding.rlBatterySemicolon.visibility = View.VISIBLE - if (rileyLinkServiceData.batteryLevel == null) { - binding.rlBatteryState.text = " ?" - } else { - binding.rlBatteryState.text = "{fa-battery-" + rileyLinkServiceData.batteryLevel / 25 + "} " + rileyLinkServiceData.batteryLevel + "%" - } + binding.rlBatteryState.text = + if (rileyLinkServiceData.batteryLevel == null) " ?" + else "{fa-battery-${rileyLinkServiceData.batteryLevel!! / 25}} ${rileyLinkServiceData.batteryLevel}%" } else { binding.rlBatteryView.visibility = View.GONE binding.rlBatteryLabel.visibility = View.GONE diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.kt b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.kt index 1fb2ca414c..1177388890 100644 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.kt +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.kt @@ -110,7 +110,7 @@ class RileyLinkBroadcastReceiver : DaggerBroadcastReceiver() { aapsLogger.debug(LTag.PUMPBTCOMM, "RfSpy version (BLE113): $bleVersion") rileyLinkService?.rileyLinkServiceData?.versionBLE113 = bleVersion - aapsLogger.debug(LTag.PUMPBTCOMM, "RfSpy Radio version (CC110): " + rlVersion.name) + aapsLogger.debug(LTag.PUMPBTCOMM, "RfSpy Radio version (CC110): ${rlVersion?.name}") rileyLinkServiceData.firmwareVersion = rlVersion val task: ServiceTask = InitializePumpManagerTask(injector, context) serviceTaskExecutor.startTask(task) diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.java b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.java index e6f3f30889..7876fb1f1f 100644 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.java +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.java @@ -31,27 +31,27 @@ public class RileyLinkServiceData { @Inject RxBus rxBus; boolean tuneUpDone = false; - public RileyLinkError rileyLinkError; + @Nullable public RileyLinkError rileyLinkError; public RileyLinkServiceState rileyLinkServiceState = RileyLinkServiceState.NotStarted; private long lastServiceStateChange = 0L; - public RileyLinkFirmwareVersion firmwareVersion; // here we have "compatibility level" version + @Nullable public RileyLinkFirmwareVersion firmwareVersion; // here we have "compatibility level" version @Nullable public RileyLinkTargetFrequency rileyLinkTargetFrequency; @Nullable public String rileyLinkAddress; @Nullable public String rileyLinkName; - public Integer batteryLevel; + @Nullable public Integer batteryLevel; public boolean showBatteryLevel = false; long lastTuneUpTime = 0L; - public Double lastGoodFrequency; + @Nullable public Double lastGoodFrequency; // bt version - public String versionBLE113; + @Nullable public String versionBLE113; // radio version - public String versionCC110; + @Nullable public String versionCC110; // orangeLink - public boolean isOrange; - public String versionOrangeFirmware; - public String versionOrangeHardware; + public boolean isOrange = false; + @Nullable public String versionOrangeFirmware; + @Nullable public String versionOrangeHardware; public RileyLinkTargetDevice targetDevice; diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/InitializePumpManagerTask.kt b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/InitializePumpManagerTask.kt index 2b43ea0ea3..903200d3d4 100644 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/InitializePumpManagerTask.kt +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/InitializePumpManagerTask.kt @@ -34,8 +34,7 @@ class InitializePumpManagerTask(injector: HasAndroidInjector, private val contex lastGoodFrequency = sp.getDouble(RileyLinkConst.Prefs.LastGoodDeviceFrequency, 0.0) lastGoodFrequency = (lastGoodFrequency * 1000.0).roundToLong() / 1000.0 rileyLinkServiceData.lastGoodFrequency = lastGoodFrequency - - } else lastGoodFrequency = rileyLinkServiceData.lastGoodFrequency + } else lastGoodFrequency = rileyLinkServiceData.lastGoodFrequency ?: 0.0 val rileyLinkCommunicationManager = pumpDevice?.rileyLinkService?.deviceCommunicationManager if (activePlugin.activePump.manufacturer() === ManufacturerType.Medtronic) { From 9e29cbc2febf7a5359c7f0e07ccc644f9d2fddb5 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 1 Jul 2022 00:33:19 +0200 Subject: [PATCH 11/63] RileyLinkServiceData -> kt --- .../pump/medtronic/MedtronicFragment.kt | 2 +- .../omnipod/eros/OmnipodErosPumpPlugin.java | 4 +- .../service/RileyLinkOmnipodService.java | 4 +- .../dialog/RileyLinkStatusGeneralFragment.kt | 2 +- .../service/RileyLinkBroadcastReceiver.kt | 2 +- .../hw/rileylink/service/RileyLinkService.kt | 25 ++--- .../service/RileyLinkServiceData.java | 103 ------------------ .../rileylink/service/RileyLinkServiceData.kt | 73 +++++++++++++ .../tasks/InitializePumpManagerTask.kt | 8 +- 9 files changed, 91 insertions(+), 132 deletions(-) delete mode 100644 rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.java create mode 100644 rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt index 86666790a5..84ac9a6138 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicFragment.kt @@ -188,7 +188,7 @@ class MedtronicFragment : DaggerFragment() { @Synchronized private fun setDeviceStatus() { val resourceId = rileyLinkServiceData.rileyLinkServiceState.resourceId - val rileyLinkError = medtronicPumpPlugin.rileyLinkService?.error + val rileyLinkError =rileyLinkServiceData.rileyLinkError binding.rlStatus.text = when { rileyLinkServiceData.rileyLinkServiceState == RileyLinkServiceState.NotStarted -> rh.gs(resourceId) diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java b/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java index 402d836bb3..f4c1bb19c7 100644 --- a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java +++ b/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/OmnipodErosPumpPlugin.java @@ -375,7 +375,7 @@ public class OmnipodErosPumpPlugin extends PumpPluginBase implements Pump, Riley } public boolean isRileyLinkReady() { - return rileyLinkServiceData.rileyLinkServiceState.isReady(); + return rileyLinkServiceData.getRileyLinkServiceState().isReady(); } private void handleCancelledTbr() { @@ -1014,7 +1014,7 @@ public class OmnipodErosPumpPlugin extends PumpPluginBase implements Pump, Riley // - RileyLink has been connecting for over RILEY_LINK_CONNECT_TIMEOUT return (podStateManager.getLastFailedCommunication() != null && podStateManager.getLastSuccessfulCommunication().isBefore(podStateManager.getLastFailedCommunication())) || podStateManager.isSuspended() || - rileyLinkServiceData.rileyLinkServiceState.isError() || + rileyLinkServiceData.getRileyLinkServiceState().isError() || // The below clause is a hack for working around the RL service state forever staying in connecting state on startup if the RL is switched off / unreachable (rileyLinkServiceData.getRileyLinkServiceState().isConnecting() && rileyLinkServiceData.getLastServiceStateChange() + RILEY_LINK_CONNECT_TIMEOUT_MILLIS < currentTimeMillis); } diff --git a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/rileylink/service/RileyLinkOmnipodService.java b/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/rileylink/service/RileyLinkOmnipodService.java index 8520db88d3..c6a7d37063 100644 --- a/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/rileylink/service/RileyLinkOmnipodService.java +++ b/omnipod-eros/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/eros/rileylink/service/RileyLinkOmnipodService.java @@ -97,10 +97,8 @@ public class RileyLinkOmnipodService extends RileyLinkService { /* private functions */ - // PumpInterface - REMOVE - public boolean isInitialized() { - return rileyLinkServiceData.rileyLinkServiceState.isReady(); + return rileyLinkServiceData.getRileyLinkServiceState().isReady(); } @Override diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/dialog/RileyLinkStatusGeneralFragment.kt b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/dialog/RileyLinkStatusGeneralFragment.kt index 115849b46d..d9b6ee141c 100644 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/dialog/RileyLinkStatusGeneralFragment.kt +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/dialog/RileyLinkStatusGeneralFragment.kt @@ -72,7 +72,7 @@ class RileyLinkStatusGeneralFragment : DaggerFragment() { } val rileyLinkPumpDevice = activePlugin.activePump as RileyLinkPumpDevice val rileyLinkPumpInfo = rileyLinkPumpDevice.pumpInfo - binding.deviceType.setText(targetDevice.resourceId) + targetDevice?.resourceId?.let { binding.deviceType.setText(it) } if (targetDevice == RileyLinkTargetDevice.MedtronicPump) { binding.connectedDeviceDetails.visibility = View.VISIBLE binding.configuredDeviceModel.text = activePlugin.activePump.pumpDescription.pumpType.description diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.kt b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.kt index 1177388890..ff9fca17f3 100644 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.kt +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkBroadcastReceiver.kt @@ -153,7 +153,7 @@ class RileyLinkBroadcastReceiver : DaggerBroadcastReceiver() { private fun processTuneUpBroadcasts(action: String): Boolean = if (broadcastIdentifiers["TuneUp"]?.contains(action) == true) { - if (rileyLinkService?.rileyLinkTargetDevice?.isTuneUpEnabled == true) serviceTaskExecutor.startTask(WakeAndTuneTask(injector)) + if (rileyLinkServiceData.targetDevice?.isTuneUpEnabled == true) serviceTaskExecutor.startTask(WakeAndTuneTask(injector)) true } else false } \ No newline at end of file diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkService.kt b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkService.kt index d7503bf2a6..d7efd6ca73 100644 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkService.kt +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkService.kt @@ -94,7 +94,7 @@ abstract class RileyLinkService : DaggerService() { fun bluetoothInit(): Boolean { aapsLogger.debug(LTag.PUMPBTCOMM, "bluetoothInit: attempting to get an adapter") - rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.BluetoothInitializing) + rileyLinkServiceData.rileyLinkServiceState = RileyLinkServiceState.BluetoothInitializing if (bluetoothAdapter == null) { aapsLogger.error("Unable to obtain a BluetoothAdapter.") rileyLinkServiceData.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.NoBluetoothAdapter) @@ -103,7 +103,7 @@ abstract class RileyLinkService : DaggerService() { aapsLogger.error("Bluetooth is not enabled.") rileyLinkServiceData.setServiceState(RileyLinkServiceState.BluetoothError, RileyLinkError.BluetoothDisabled) } else { - rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.BluetoothReady) + rileyLinkServiceData.rileyLinkServiceState = RileyLinkServiceState.BluetoothReady return true } } @@ -112,7 +112,7 @@ abstract class RileyLinkService : DaggerService() { // returns true if our Rileylink configuration changed fun reconfigureRileyLink(deviceAddress: String): Boolean { - rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.RileyLinkInitializing) + rileyLinkServiceData.rileyLinkServiceState = RileyLinkServiceState.RileyLinkInitializing return if (rileyLinkBLE.isConnected) { if (deviceAddress == rileyLinkServiceData.rileyLinkAddress) { aapsLogger.info(LTag.PUMPBTCOMM, "No change to RL address. Not reconnecting.") @@ -128,9 +128,9 @@ abstract class RileyLinkService : DaggerService() { } } else { aapsLogger.debug(LTag.PUMPBTCOMM, "Using RL $deviceAddress") - if (rileyLinkServiceData.getRileyLinkServiceState() == RileyLinkServiceState.NotStarted) { + if (rileyLinkServiceData.rileyLinkServiceState == RileyLinkServiceState.NotStarted) { if (!bluetoothInit()) { - aapsLogger.error("RileyLink can't get activated, Bluetooth is not functioning correctly. ${error?.name ?: "Unknown error (null)"}") + aapsLogger.error("RileyLink can't get activated, Bluetooth is not functioning correctly. ${rileyLinkServiceData.rileyLinkError?.name ?: "Unknown error (null)"}") return false } } @@ -141,7 +141,7 @@ abstract class RileyLinkService : DaggerService() { // FIXME: This needs to be run in a session so that is incorruptible, has a separate thread, etc. fun doTuneUpDevice() { - rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.TuneUpDevice) + rileyLinkServiceData.rileyLinkServiceState = RileyLinkServiceState.TuneUpDevice setPumpDeviceState(PumpDeviceState.Sleeping) val lastGoodFrequency = rileyLinkServiceData.lastGoodFrequency ?: sp.getDouble(RileyLinkConst.Prefs.LastGoodDeviceFrequency, 0.0) val newFrequency = deviceCommunicationManager.tuneForDevice() @@ -157,7 +157,7 @@ abstract class RileyLinkService : DaggerService() { rileyLinkServiceData.setServiceState(RileyLinkServiceState.PumpConnectorError, RileyLinkError.TuneUpOfDeviceFailed) } else { deviceCommunicationManager.clearNotConnectedCount() - rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.PumpConnectorReady) + rileyLinkServiceData.rileyLinkServiceState = RileyLinkServiceState.PumpConnectorReady } } @@ -168,22 +168,13 @@ abstract class RileyLinkService : DaggerService() { rileyLinkServiceData.rileyLinkAddress = null rileyLinkServiceData.rileyLinkName = null } - rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.BluetoothReady) + rileyLinkServiceData.rileyLinkServiceState = RileyLinkServiceState.BluetoothReady } - /** - * Get Target Device for Service - */ - val rileyLinkTargetDevice: RileyLinkTargetDevice - get() = rileyLinkServiceData.targetDevice - fun changeRileyLinkEncoding(encodingType: RileyLinkEncodingType?) { rfSpy.setRileyLinkEncoding(encodingType) } - val error: RileyLinkError? - get() = rileyLinkServiceData.rileyLinkError - fun verifyConfiguration(): Boolean { return verifyConfiguration(false) } diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.java b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.java deleted file mode 100644 index 7876fb1f1f..0000000000 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.java +++ /dev/null @@ -1,103 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service; - -import java.util.Locale; - -import javax.annotation.Nullable; -import javax.inject.Inject; -import javax.inject.Singleton; - -import info.nightscout.androidaps.plugins.bus.RxBus; -import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkFirmwareVersion; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkTargetFrequency; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice; -import info.nightscout.shared.logging.AAPSLogger; -import info.nightscout.shared.logging.LTag; - -/** - * Created by andy on 16/05/2018. - */ - -// FIXME encapsulation -@Singleton -public class RileyLinkServiceData { - - @Inject AAPSLogger aapsLogger; - @Inject RileyLinkUtil rileyLinkUtil; - @Inject RxBus rxBus; - - boolean tuneUpDone = false; - @Nullable public RileyLinkError rileyLinkError; - public RileyLinkServiceState rileyLinkServiceState = RileyLinkServiceState.NotStarted; - private long lastServiceStateChange = 0L; - @Nullable public RileyLinkFirmwareVersion firmwareVersion; // here we have "compatibility level" version - @Nullable public RileyLinkTargetFrequency rileyLinkTargetFrequency; - @Nullable public String rileyLinkAddress; - @Nullable public String rileyLinkName; - @Nullable public Integer batteryLevel; - public boolean showBatteryLevel = false; - long lastTuneUpTime = 0L; - @Nullable public Double lastGoodFrequency; - - // bt version - @Nullable public String versionBLE113; - // radio version - @Nullable public String versionCC110; - - // orangeLink - public boolean isOrange = false; - @Nullable public String versionOrangeFirmware; - @Nullable public String versionOrangeHardware; - - public RileyLinkTargetDevice targetDevice; - - // Medtronic Pump - public String pumpID; - public byte[] pumpIDBytes; - - @Inject - public RileyLinkServiceData() { - } - - public void setPumpID(String pumpId, byte[] pumpIdBytes) { - this.pumpID = pumpId; - this.pumpIDBytes = pumpIdBytes; - } - - public void setRileyLinkServiceState(RileyLinkServiceState newState) { - setServiceState(newState, null); - } - - public RileyLinkServiceState getRileyLinkServiceState() { - return workWithServiceState(null, null, false); - } - - public void setServiceState(RileyLinkServiceState newState, RileyLinkError errorCode) { - workWithServiceState(newState, errorCode, true); - } - - public long getLastServiceStateChange() { - return lastServiceStateChange; - } - - private synchronized RileyLinkServiceState workWithServiceState(RileyLinkServiceState newState, RileyLinkError errorCode, boolean set) { - if (set) { - rileyLinkServiceState = newState; - lastServiceStateChange = System.currentTimeMillis(); - this.rileyLinkError = errorCode; - - aapsLogger.info(LTag.PUMP, String.format(Locale.ENGLISH, "RileyLink State Changed: %s %s", newState, errorCode == null ? "" : " - Error State: " + errorCode.name())); - - rileyLinkUtil.getRileyLinkHistory().add(new RLHistoryItem(rileyLinkServiceState, errorCode, targetDevice)); - rxBus.send(new EventRileyLinkDeviceStatusChange(targetDevice, newState, errorCode)); - return null; - } else { - return rileyLinkServiceState; - } - } - -} diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.kt b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.kt new file mode 100644 index 0000000000..047467fd7f --- /dev/null +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.kt @@ -0,0 +1,73 @@ +package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service + +import info.nightscout.androidaps.plugins.bus.RxBus +import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkFirmwareVersion +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkTargetFrequency +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.data.RLHistoryItem +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice +import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.logging.LTag +import java.util.* +import javax.inject.Inject +import javax.inject.Singleton + +/** + * Created by andy on 16/05/2018. + */ +@Singleton +class RileyLinkServiceData @Inject constructor() { + + @Inject lateinit var aapsLogger: AAPSLogger + @Inject lateinit var rileyLinkUtil: RileyLinkUtil + @Inject lateinit var rxBus: RxBus + var tuneUpDone = false + var rileyLinkError: RileyLinkError? = null + var rileyLinkServiceState: RileyLinkServiceState = RileyLinkServiceState.NotStarted + var lastServiceStateChange = 0L + private set + + // here we have "compatibility level" version + @JvmField var firmwareVersion: RileyLinkFirmwareVersion? = null + @JvmField var rileyLinkTargetFrequency: RileyLinkTargetFrequency? = null + @JvmField var rileyLinkAddress: String? = null + @JvmField var rileyLinkName: String? = null + @JvmField var batteryLevel: Int? = null + var showBatteryLevel = false + var lastTuneUpTime = 0L + var lastGoodFrequency: Double? = null + + // bt version + var versionBLE113: String? = null + + // radio version + @JvmField var versionCC110: String? = null + + // orangeLink + var isOrange = false + var versionOrangeFirmware: String? = null + var versionOrangeHardware: String? = null + @JvmField var targetDevice: RileyLinkTargetDevice? = null + + // Medtronic Pump + var pumpID: String? = null + var pumpIDBytes: ByteArray = byteArrayOf(0, 0, 0) + + fun setPumpID(pumpId: String?, pumpIdBytes: ByteArray) { + pumpID = pumpId + pumpIDBytes = pumpIdBytes + } + + @Synchronized + fun setServiceState(newState: RileyLinkServiceState, errorCode: RileyLinkError) { + rileyLinkServiceState = newState + lastServiceStateChange = System.currentTimeMillis() + rileyLinkError = errorCode + aapsLogger.info(LTag.PUMP, String.format(Locale.ENGLISH, "RileyLink State Changed: $newState - Error State: ${errorCode.name}")) + rileyLinkUtil.rileyLinkHistory.add(RLHistoryItem(rileyLinkServiceState, errorCode, targetDevice)) + rxBus.send(EventRileyLinkDeviceStatusChange(targetDevice!!, newState, errorCode)) + } +} \ No newline at end of file diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/InitializePumpManagerTask.kt b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/InitializePumpManagerTask.kt index 903200d3d4..935aff66bc 100644 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/InitializePumpManagerTask.kt +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/tasks/InitializePumpManagerTask.kt @@ -39,10 +39,10 @@ class InitializePumpManagerTask(injector: HasAndroidInjector, private val contex val rileyLinkCommunicationManager = pumpDevice?.rileyLinkService?.deviceCommunicationManager if (activePlugin.activePump.manufacturer() === ManufacturerType.Medtronic) { if (lastGoodFrequency > 0.0 && rileyLinkCommunicationManager?.isValidFrequency(lastGoodFrequency) == true) { - rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.RileyLinkReady) + rileyLinkServiceData.rileyLinkServiceState = RileyLinkServiceState.RileyLinkReady aapsLogger.info(LTag.PUMPBTCOMM, "Setting radio frequency to $lastGoodFrequency MHz") rileyLinkCommunicationManager.setRadioFrequencyForPump(lastGoodFrequency) - if (rileyLinkCommunicationManager.tryToConnectToDevice()) rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.PumpConnectorReady) + if (rileyLinkCommunicationManager.tryToConnectToDevice()) rileyLinkServiceData.rileyLinkServiceState = RileyLinkServiceState.PumpConnectorReady else { rileyLinkServiceData.setServiceState(RileyLinkServiceState.PumpConnectorError, RileyLinkError.NoContactWithDevice) rileyLinkUtil.sendBroadcastMessage(RileyLinkConst.IPC.MSG_PUMP_tunePump, context) @@ -54,11 +54,11 @@ class InitializePumpManagerTask(injector: HasAndroidInjector, private val contex lastGoodFrequency = (lastGoodFrequency * 1000.0).roundToLong() / 1000.0 rileyLinkServiceData.lastGoodFrequency = lastGoodFrequency } - rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.RileyLinkReady) + rileyLinkServiceData.rileyLinkServiceState = RileyLinkServiceState.RileyLinkReady rileyLinkServiceData.rileyLinkTargetFrequency = RileyLinkTargetFrequency.Omnipod // TODO shouldn't be needed aapsLogger.info(LTag.PUMPBTCOMM, "Setting radio frequency to $lastGoodFrequency MHz") rileyLinkCommunicationManager?.setRadioFrequencyForPump(lastGoodFrequency) - rileyLinkServiceData.setRileyLinkServiceState(RileyLinkServiceState.PumpConnectorReady) + rileyLinkServiceData.rileyLinkServiceState = RileyLinkServiceState.PumpConnectorReady } } } \ No newline at end of file From c9a039a8a690629babf5a43e2bbf07b1dd04936f Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 1 Jul 2022 00:51:05 +0200 Subject: [PATCH 12/63] RL: enum -> kt --- .../service/RileyLinkMedtronicService.kt | 2 +- .../pump/common/hw/rileylink/ble/RFSpy.java | 6 ++--- .../hw/rileylink/ble/defs/RLMessageType.java | 10 -------- .../hw/rileylink/ble/defs/RLMessageType.kt | 10 ++++++++ .../hw/rileylink/ble/defs/RXFilterMode.java | 19 -------------- .../hw/rileylink/ble/defs/RXFilterMode.kt | 10 ++++++++ .../ble/defs/RileyLinkTargetFrequency.java | 25 ------------------- .../ble/defs/RileyLinkTargetFrequency.kt | 11 ++++++++ 8 files changed, 35 insertions(+), 58 deletions(-) delete mode 100644 rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RLMessageType.java create mode 100644 rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RLMessageType.kt delete mode 100644 rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RXFilterMode.java create mode 100644 rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RXFilterMode.kt delete mode 100644 rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkTargetFrequency.java create mode 100644 rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkTargetFrequency.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/service/RileyLinkMedtronicService.kt b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/service/RileyLinkMedtronicService.kt index e5157aadec..4154965d3b 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/service/RileyLinkMedtronicService.kt +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/service/RileyLinkMedtronicService.kt @@ -177,7 +177,7 @@ class RileyLinkMedtronicService : RileyLinkService() { medtronicPumpStatus.pumpFrequency = pumpFrequency val isFrequencyUS = pumpFrequency == frequencies[0] val newTargetFrequency = if (isFrequencyUS) // - RileyLinkTargetFrequency.Medtronic_US else RileyLinkTargetFrequency.Medtronic_WorldWide + RileyLinkTargetFrequency.MedtronicUS else RileyLinkTargetFrequency.MedtronicWorldWide if (rileyLinkServiceData.rileyLinkTargetFrequency != newTargetFrequency) { rileyLinkServiceData.rileyLinkTargetFrequency = newTargetFrequency } diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpy.java b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpy.java index abd0bd5d83..356628cce8 100644 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpy.java +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpy.java @@ -309,7 +309,7 @@ public class RFSpy { aapsLogger.error(LTag.PUMPBTCOMM, "RileyLinkTargetFrequency: " + frequency); switch (frequency) { - case Medtronic_WorldWide: + case MedtronicWorldWide: setRXFilterMode(RXFilterMode.Wide); updateRegister(CC111XRegister.mdmcfg1, 0x62); updateRegister(CC111XRegister.mdmcfg0, 0x1A); @@ -317,7 +317,7 @@ public class RFSpy { setMedtronicEncoding(); break; - case Medtronic_US: + case MedtronicUS: setRXFilterMode(RXFilterMode.Narrow); updateRegister(CC111XRegister.mdmcfg1, 0x61); updateRegister(CC111XRegister.mdmcfg0, 0x7E); @@ -400,7 +400,7 @@ public class RFSpy { private void setRXFilterMode(RXFilterMode mode) { byte drate_e = (byte) 0x9; // exponent of symbol rate (16kbps) - byte chanbw = mode.value; + byte chanbw = mode.getValue(); updateRegister(CC111XRegister.mdmcfg4, (byte) (chanbw | drate_e)); } diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RLMessageType.java b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RLMessageType.java deleted file mode 100644 index 7cc11da498..0000000000 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RLMessageType.java +++ /dev/null @@ -1,10 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs; - -/** - * Created by andy on 5/6/18. - */ - -public enum RLMessageType { - PowerOn, // for powering on the pump (wakeup) - ReadSimpleData, // for checking if pump is readable (for Medtronic we can use GetModel) -} diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RLMessageType.kt b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RLMessageType.kt new file mode 100644 index 0000000000..f64cd6666f --- /dev/null +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RLMessageType.kt @@ -0,0 +1,10 @@ +package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs + +/** + * Created by andy on 5/6/18. + */ +enum class RLMessageType { + + PowerOn, // for powering on the pump (wakeup) + ReadSimpleData // for checking if pump is readable (for Medtronic we can use GetModel) +} \ No newline at end of file diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RXFilterMode.java b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RXFilterMode.java deleted file mode 100644 index e50929ebfe..0000000000 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RXFilterMode.java +++ /dev/null @@ -1,19 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs; - -/** - * Created by andy on 21/05/2018. - */ - -public enum RXFilterMode { - - Wide(0x50), // - Narrow(0x90) // - ; - - public byte value; - - - RXFilterMode(int value) { - this.value = (byte)value; - } -} diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RXFilterMode.kt b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RXFilterMode.kt new file mode 100644 index 0000000000..9150be1789 --- /dev/null +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RXFilterMode.kt @@ -0,0 +1,10 @@ +package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs + +/** + * Created by andy on 21/05/2018. + */ +enum class RXFilterMode(val value: Byte) { + + Wide(0x50), + Narrow(0x90.toByte()); +} \ No newline at end of file diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkTargetFrequency.java b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkTargetFrequency.java deleted file mode 100644 index 0d7f341584..0000000000 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkTargetFrequency.java +++ /dev/null @@ -1,25 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs; - -/** - * Created by andy on 6/7/18. - */ - -public enum RileyLinkTargetFrequency { - - Medtronic_WorldWide(868.25, 868.3, 868.35, 868.4, 868.45, 868.5, 868.55, 868.6, 868.65), // - Medtronic_US(916.45, 916.5, 916.55, 916.6, 916.65, 916.7, 916.75, 916.8), // - Omnipod(433.91), // - ; - - double[] frequencies; - - - RileyLinkTargetFrequency(double... frequencies) { - this.frequencies = frequencies; - } - - - public double[] getScanFrequencies() { - return frequencies; - } -} diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkTargetFrequency.kt b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkTargetFrequency.kt new file mode 100644 index 0000000000..8a50374cde --- /dev/null +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/defs/RileyLinkTargetFrequency.kt @@ -0,0 +1,11 @@ +package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs + +/** + * Created by andy on 6/7/18. + */ +enum class RileyLinkTargetFrequency(vararg var scanFrequencies: Double) { + + MedtronicWorldWide(868.25, 868.3, 868.35, 868.4, 868.45, 868.5, 868.55, 868.6, 868.65), + MedtronicUS(916.45, 916.5, 916.55, 916.6, 916.65, 916.7, 916.75, 916.8), + Omnipod(433.91); +} \ No newline at end of file From 7b8a3d8988b4ed19d5bd898bb2ba5bdde0abecf4 Mon Sep 17 00:00:00 2001 From: Philoul Date: Fri, 1 Jul 2022 01:26:19 +0200 Subject: [PATCH 13/63] wear vector icons replace png by xml --- icons/action_add.svg | 10 +++ icons/action_minus.svg | 7 +++ icons/cancel.svg | 13 ++++ icons/confirm.svg | 8 +++ icons/icon_snooze.svg | 59 ++++++++++++++++++ icons/loop.svg | 10 +++ icons/setting_off.svg | 8 +++ icons/setting_on.svg | 8 +++ wear/src/main/res/drawable-hdpi/ic_cancel.png | Bin 991 -> 0 bytes .../src/main/res/drawable-hdpi/ic_confirm.png | Bin 291 -> 0 bytes .../main/res/drawable-hdpi/settings_off.png | Bin 851 -> 0 bytes .../main/res/drawable-hdpi/settings_on.png | Bin 601 -> 0 bytes wear/src/main/res/drawable-mdpi/ic_cancel.png | Bin 601 -> 0 bytes .../src/main/res/drawable-mdpi/ic_confirm.png | Bin 196 -> 0 bytes .../main/res/drawable-mdpi/settings_off.png | Bin 551 -> 0 bytes .../main/res/drawable-mdpi/settings_on.png | Bin 408 -> 0 bytes .../src/main/res/drawable-xhdpi/ic_cancel.png | Bin 1234 -> 0 bytes .../main/res/drawable-xhdpi/ic_confirm.png | Bin 289 -> 0 bytes .../main/res/drawable-xhdpi/settings_off.png | Bin 1091 -> 0 bytes .../main/res/drawable-xhdpi/settings_on.png | Bin 779 -> 0 bytes .../main/res/drawable-xxhdpi/ic_cancel.png | Bin 2121 -> 0 bytes .../main/res/drawable-xxhdpi/ic_confirm.png | Bin 462 -> 0 bytes .../main/res/drawable-xxhdpi/settings_off.png | Bin 1848 -> 0 bytes .../main/res/drawable-xxhdpi/settings_on.png | Bin 1285 -> 0 bytes wear/src/main/res/drawable/ic_action_add.png | Bin 139 -> 0 bytes wear/src/main/res/drawable/ic_action_add.xml | 9 +++ .../src/main/res/drawable/ic_action_minus.png | Bin 131 -> 0 bytes .../src/main/res/drawable/ic_action_minus.xml | 8 +++ wear/src/main/res/drawable/ic_cancel.xml | 16 +++++ wear/src/main/res/drawable/ic_confirm.xml | 8 +++ wear/src/main/res/drawable/ic_icon.png | Bin 3218 -> 0 bytes wear/src/main/res/drawable/ic_icon.xml | 16 +++++ wear/src/main/res/drawable/ic_icon_snooze.png | Bin 24861 -> 0 bytes wear/src/main/res/drawable/ic_icon_snooze.xml | 18 ++++++ wear/src/main/res/drawable/loop_green_25.png | Bin 21623 -> 0 bytes wear/src/main/res/drawable/loop_green_25.xml | 9 +++ wear/src/main/res/drawable/loop_grey_25.png | Bin 22321 -> 0 bytes wear/src/main/res/drawable/loop_grey_25.xml | 9 +++ wear/src/main/res/drawable/loop_red_25.png | Bin 21623 -> 0 bytes wear/src/main/res/drawable/loop_red_25.xml | 9 +++ wear/src/main/res/drawable/settings_off.xml | 10 +++ wear/src/main/res/drawable/settings_on.xml | 10 +++ 42 files changed, 245 insertions(+) create mode 100644 icons/action_add.svg create mode 100644 icons/action_minus.svg create mode 100644 icons/cancel.svg create mode 100644 icons/confirm.svg create mode 100644 icons/icon_snooze.svg create mode 100644 icons/loop.svg create mode 100644 icons/setting_off.svg create mode 100644 icons/setting_on.svg delete mode 100644 wear/src/main/res/drawable-hdpi/ic_cancel.png delete mode 100644 wear/src/main/res/drawable-hdpi/ic_confirm.png delete mode 100644 wear/src/main/res/drawable-hdpi/settings_off.png delete mode 100644 wear/src/main/res/drawable-hdpi/settings_on.png delete mode 100644 wear/src/main/res/drawable-mdpi/ic_cancel.png delete mode 100644 wear/src/main/res/drawable-mdpi/ic_confirm.png delete mode 100644 wear/src/main/res/drawable-mdpi/settings_off.png delete mode 100644 wear/src/main/res/drawable-mdpi/settings_on.png delete mode 100644 wear/src/main/res/drawable-xhdpi/ic_cancel.png delete mode 100644 wear/src/main/res/drawable-xhdpi/ic_confirm.png delete mode 100644 wear/src/main/res/drawable-xhdpi/settings_off.png delete mode 100644 wear/src/main/res/drawable-xhdpi/settings_on.png delete mode 100644 wear/src/main/res/drawable-xxhdpi/ic_cancel.png delete mode 100644 wear/src/main/res/drawable-xxhdpi/ic_confirm.png delete mode 100644 wear/src/main/res/drawable-xxhdpi/settings_off.png delete mode 100644 wear/src/main/res/drawable-xxhdpi/settings_on.png delete mode 100644 wear/src/main/res/drawable/ic_action_add.png create mode 100644 wear/src/main/res/drawable/ic_action_add.xml delete mode 100644 wear/src/main/res/drawable/ic_action_minus.png create mode 100644 wear/src/main/res/drawable/ic_action_minus.xml create mode 100644 wear/src/main/res/drawable/ic_cancel.xml create mode 100644 wear/src/main/res/drawable/ic_confirm.xml delete mode 100644 wear/src/main/res/drawable/ic_icon.png create mode 100644 wear/src/main/res/drawable/ic_icon.xml delete mode 100644 wear/src/main/res/drawable/ic_icon_snooze.png create mode 100644 wear/src/main/res/drawable/ic_icon_snooze.xml delete mode 100644 wear/src/main/res/drawable/loop_green_25.png create mode 100644 wear/src/main/res/drawable/loop_green_25.xml delete mode 100644 wear/src/main/res/drawable/loop_grey_25.png create mode 100644 wear/src/main/res/drawable/loop_grey_25.xml delete mode 100644 wear/src/main/res/drawable/loop_red_25.png create mode 100644 wear/src/main/res/drawable/loop_red_25.xml create mode 100644 wear/src/main/res/drawable/settings_off.xml create mode 100644 wear/src/main/res/drawable/settings_on.xml diff --git a/icons/action_add.svg b/icons/action_add.svg new file mode 100644 index 0000000000..929dd4f7d9 --- /dev/null +++ b/icons/action_add.svg @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/icons/action_minus.svg b/icons/action_minus.svg new file mode 100644 index 0000000000..c7ef549809 --- /dev/null +++ b/icons/action_minus.svg @@ -0,0 +1,7 @@ + + + + + + diff --git a/icons/cancel.svg b/icons/cancel.svg new file mode 100644 index 0000000000..070444ebd3 --- /dev/null +++ b/icons/cancel.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + diff --git a/icons/confirm.svg b/icons/confirm.svg new file mode 100644 index 0000000000..0e93b2634e --- /dev/null +++ b/icons/confirm.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/icons/icon_snooze.svg b/icons/icon_snooze.svg new file mode 100644 index 0000000000..c2190ac542 --- /dev/null +++ b/icons/icon_snooze.svg @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + diff --git a/icons/loop.svg b/icons/loop.svg new file mode 100644 index 0000000000..b9e96b325d --- /dev/null +++ b/icons/loop.svg @@ -0,0 +1,10 @@ + + + + + + diff --git a/icons/setting_off.svg b/icons/setting_off.svg new file mode 100644 index 0000000000..ae79852ac7 --- /dev/null +++ b/icons/setting_off.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/icons/setting_on.svg b/icons/setting_on.svg new file mode 100644 index 0000000000..72d9d52c8b --- /dev/null +++ b/icons/setting_on.svg @@ -0,0 +1,8 @@ + + + + + + diff --git a/wear/src/main/res/drawable-hdpi/ic_cancel.png b/wear/src/main/res/drawable-hdpi/ic_cancel.png deleted file mode 100644 index f3f1437a8855f7c2a6ac613ec1c895a305f3b36b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 991 zcmV<510ei~P)VW$!s4=cnOez&4;IF`$9*KMNQGBmgl)0zaDrQ~|#wI&J`)fRJh9qkwmk zhkgM(7kf1I31_}ZbRGa6n|$+}@mGK)L6aTm9ssOJ?$UvglK>^J80F&4r3{{MM#5y9 zohqJUVqWlh(kDv($lQrsCsg@^DE#V&@x+M}hMk5?gpP>$XI-G_409(obd`((nncNh zi%d{Mf6(Ro6(-pY>p1X|C^&Xv8^IQUB49#6cOJ0gR0|@{rgDMLZ2}?-4{By^%b{d;4I82_LFCUI+f$^k1_^_xW)9)PNjYqYt{6GN3&-M7 zu#Eu+a*`&-a-vvM4unXzr5i#V+eq2Tj}Qt1J`tgm#+&EZhGi#@m-tXcXrBm8dkmW< zelBCDtb*QIB3Dsy-~|yXc?g?-*hVGUNpx3;%%X||<3#9Eu#-b6QC49a2|E>CN{I&9 zpHc0BzZ1cN%l@iLk|HNjcItU?P@rGTq3}8p{_IjthtZ(CVxB0u7$3oDhuwxX9sYg7 z#O%D=Fjr^r>+<~)b6-YuyRz3ri70KKcA=$AVf$)-_Ldh#Nx)C0GmHCZe3I$J>Ykq| zE-y1y`QV2WXnc)4OFVnBQ^jwXlHk~6IEiToj%?_2woND(jPRaOF7Cv9hoi*^{@`)N z=ojP6u&Fl`lQ?llu?1PObEtY}@FZ^~#z#%ZXavJaHeSC(exF7r8N_TF#lO>N^ezqx zI2|nb~txul&>G#zmlnL)p!soCVP$y4phz+qJ zHt!1`#P={gIBYchLl+#^l-LX#dH6mG@1hb0Vz&tkh_Cvp(-JMjZWEPozm$+`C-GFp zZlfh`nG$B<{-fAd^^y7(C!M^l@+0*Lr>d}7iIasm+Z1rZIolL)f;!vea2jBKgCsa% p9El4h@WLl0FvC+6MN!n2dI29vujRZ{tZ4uM002ovPDHLkV1jK1eA55` diff --git a/wear/src/main/res/drawable-hdpi/settings_off.png b/wear/src/main/res/drawable-hdpi/settings_off.png deleted file mode 100644 index ab7e4249a7461ff1076114567767c118dec989ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 851 zcmV-Z1FZasP)i}y zB1WsC*4vY<7;WnR6u$#!w2)(#V-akLhuQ2MqE#Wg|+O!DIt~|X`vXvvEZLmwJN>=yc0r) zMBRwEKM7*B=s>p+S)|1*>bCGbtG+8}aSK2*Xan28UXTW7!DTQCJ_v#1O8Y0Go}SHt zD2d;q&AOjAAO=axTT1ZiH2QGn|-~o66zJghs zKIyrH+v!vf&KZl3IyhF*{B+jmQKLWlJwRHjF`DN2=$%o0u(F2uUo===bQk+Wrobek5rhjgH10FD%_AZI@$)P1<7H{fY<6d0Uemz5;72u(cYzG;BQw z%lr;%&Aj`_j=#ys>%d04vZdZ7+d<|%LxzBE7wz{LZ3ng35yUqid01(2nRd%VPv?9j zZy6yVUqSoVqW#JFaNv%XIvdY4QB=378y4+v2Q5Cvq2Cg4L`e#FgEu_VNi%xmx<|DC z>}6nd;=p<_hw1McQMZ!cj+qkVKlC;oNTE7DHxTg dMCCs$e*v^!I(?3=8TSAH002ovPDHLkV1g3Rj8Xsq diff --git a/wear/src/main/res/drawable-hdpi/settings_on.png b/wear/src/main/res/drawable-hdpi/settings_on.png deleted file mode 100644 index d22797b946fce90ded6946503af8e5652c8daaa6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 601 zcmV-f0;c_mP)YBmy)jC_ryBArgRgI1Ldtb>TE;;Xb85qhCuQ8yKftZeg169PgfG-^b?6)Qr46Nyh*I2c? z_zIBBVc;2*+1bEk4)Ge}b`|di*9Ht+0+$^P^cxVb;g>D05O_fY=wvk=1i>6w23z1R z4+FPglkS}bqcmm*&EYj8G)PU@J~#yrAeDzWUZiO56R<~`0!B>uvMfYaa|p_fK8a!w zwUPJ@)?ekDPDLODJ}nf^=3Zo4%)G$to%pao{5u%oRfT%Mi$w8Hpj$+fb}vCZE3wU@ z)`J=6I$uMw~kuEGHYE6t)M+>4>l4GL9mr$<8d7kZHtUho>ClMZz2HNP+ n7Yq7x7L@)d=!6qa{KNPGd0x-I@hGY|00000NkvXXu0mjf#H$DU diff --git a/wear/src/main/res/drawable-mdpi/ic_cancel.png b/wear/src/main/res/drawable-mdpi/ic_cancel.png deleted file mode 100644 index a564bff32224956f3dd3ab236636b0e96c1e6a5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 601 zcmV-f0;c_mP)JeF6n9M1>SXG!l#3BHeDw(hmQ{HT<}u z980o0k~#tRL~UKNUIDBD9m$%7YnO_KcKr5r0+ys+A-0yl0M3(iSa2tEYn}<*9nKbA z=$g+_IaS!)0Jc;F3od>w1$R#TM`Q*$VsNL)5*J|%F4++onL(8pTpOB|iZBL8PMg@5 zO#&JQXBK-mY-EkeI4zR^wwysVOL}g8~euV)nMPrJ!ie#-p{0?*i(j>*N;sBA@BsBbl;wZLB<}OU{ zgBPN97{JSDO#D5&A)K?x=GI5>F7dN+J)(hOi47z}Svd>?$%ycUuYyt9>NoXk+MS&>rM^{Ls@@A94BIp=p~U9Q5gFw*IC2`F|_zz`U4Qoso~aw>T% z_$8X15U{}ntlOQu8hkJT@4#!PfEh}B39jjR%C6)^;Es|8z!*K>0L2agy_E13RDeqG zMsqzf6DhRTD(C?H^u`HF7G$<-G?$=?3<5v!ff`elfsqG_Wp?~(1SOaTY{ z!l9{Xp18WVU3j*SArdeaO)5lGLu-*FIzZB+Fqqj$W2C1MyZY4%h_5O!RPo6Bf&1*q)jeF+t;635bn>*cFJwfOr`m2P}oE zafRwpf||iZjD_4l+z!Mmfp`}XpTc7isrVGsOpw`aK+J{95i&r$j*1qe<267mMJOcr zfp|6zET0L)e8k2-8xXfr(efrx#YJi&WCY?YDp;NYGK-Sj;19$n$gmis$Cp}J(w+P;-RH>YRhG^ihU>gv-fZBvmHa0b? z)NnvJmh6>>T%Lp2KwN+&yM|K30qsZz&H&YLc+`SwzgbA?Td3gxQ1EUCVs~OnG-wG5 zYOe1D;?0y=E)K*+psJb-y*xl%48$U%UAR$z4*&pl=9zS~F>y}-00005M9?OqWFypLRL`p;z3l9Ez4FxKij%(sdE%Nn%BZ*1gBgr8^10Yvm^BJHKFbqfl{z%wA0Mxlnz6Ee$F|qG}F+jP7p9;XZ z#OL(`(CjAp8^L6*k$ApAp9O#k3BS!wlW(wi@*e>;4*IVJe6n~G>YQ?3g87(o&MLW} z3vXa9rdv@=D0Cv#trHF(Sb3X;ARHA`mod}MUI`R;oqUD})Vz94zWV2clNk@xB6EUb zsmO$b1;W9m8{fQSOrQeetgi72BK5G8Q|+O0yq1{fmDU0ZBRfyoQN@a}!-nrLAf#~p z1Tohso%Q?)$KW^FA_vK{D(*L+Q^9vP;1>OdB=0F8D#l}5{RB2)LeUXL@~QizL`Wl_ z9?WD#7$@f3YDa)~97DG<-xPwTW2vrkC227H-Q#MQZ9U@BM zGSye<&~7HcW`Do#cJd=nQ3TZ`ZAt_c^7*(S%bRb|Za#fWC_1cQ zqe-@z!D*`0D_l=K{b`+wsuBZGrqN6Ge;#U!*APc@u9c%d$M_PVY{DZOBSGAi=FM@= zgo837qBBf-Kmcm*;!GxE$vTM$&hzzWk^G=wJ<(^gw>0l>aB+zWj-K>z>%07*qoM6N<$f(sKm_y7O^ diff --git a/wear/src/main/res/drawable-xhdpi/ic_confirm.png b/wear/src/main/res/drawable-xhdpi/ic_confirm.png deleted file mode 100644 index 4609b2d62023429dfea90d7a3be31d5dbd14ef7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 289 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I1|(Ny7TyC=FFaiwLn>~)ow1Skkb!`!vemSO z3A|Dg>{en6T$7|-rdOzcp17csGn0$sT&CU6I5#Ub zNzfq{Qf3xXp_V~HVh15236&)p*<~MuiY&6CqU@v(9cG8x zWrx+9|C7zYys!-O?7sRwulumO1HUi3&(5{8GxN-|ad80!6i`3`xkHnalUaaFKRe(E zpvkYs&jJhsh5(6vbij7N1fjx@4!Cb|z%9QSUuZEtjC?;ipj&W2r(cZE1dIy~_yI`s zg9Dlbhq2Mi4(Mmbz6E?_*ZRC_{1V}9H&Humz4i}~ z=S2r}Fhj?wBH)JT54(5VYsRMnzB41wTJB$B_r3v=z2txfA^cZb?w1Jn>%CO^UNYkz z2r6FjE+7}f80$7*C!i6~1~`YM4DcB64)B{9H3FC| z@SFqq%+`iz{d2%gKo2HJz(GI_pd3&PSg18;0J8%6Zd(Co09P<<0fRy^n<`ptbz*m7k%B(VFZ?IbE<0oj)Q5gka zRhdIsC8lkV@&K=Oj=HhDDkjHfj?AcgQw~0+!LL~0S8Vd$f46YjlN1F%JVO7)c-EQh zfD267ehobDFrMd4b^tF`%^G;NFrIHrH9lMTUP~Psn{H~TGNw3E%QDdcRl+zcS<%by zWwjm4TCH?0NF#N=>DgkU15WamSXfg;vqIG#9>;Dggy){Ib;nF}03U0&Tkd60s7EsH z3XwC@EYF`}YX(d+K1DEYD}{TVqDyqb2u+mY*$-9WY0o^998fA4P)^fXm4Wz+Ts55s zjM}WbOQUyweXU6jXcl&9A)64#fkvw3`E(kngly(}eAju{BnR|I7}odj%)y3Fp+nSI zaorT-lc?pjQ+AY2kK!ZXmp~=aDQ}D!@jDG2kJ)8(%;4$M;ER=`%b{`jW3Fs!K68J_f6)C0aSSr<)kz_2CUyX^XUO@q;HOGOxR+xW$#2!?3U z49YE`Gk}Shp9453Qcj_n;DYQ#IvpyD3n-v~0tzUgfC8EZ{Rh32<6h%O>oouX002ov JPDHLkV1m<6^w0nR diff --git a/wear/src/main/res/drawable-xhdpi/settings_on.png b/wear/src/main/res/drawable-xhdpi/settings_on.png deleted file mode 100644 index db90aa602c5066ed4071315e5ad271dec6e0187b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 779 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 diff --git a/wear/src/main/res/drawable/ic_action_add.png b/wear/src/main/res/drawable/ic_action_add.png deleted file mode 100644 index ca13239a7d6102d789ddef86e219ccb44ae56950..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 139 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpUtAWs*^kcwMxZ*1gcP~dQN{1*Q! zJNXeqltbT>uQ86!sw>Zl0#yOQ0ha^w=0KPX47-@$wbrp42tDXvgbLY|Ls;{+F)({= UU3IEMqYNbD>FVdQ&MBb@0GInDp#T5? diff --git a/wear/src/main/res/drawable/ic_action_add.xml b/wear/src/main/res/drawable/ic_action_add.xml new file mode 100644 index 0000000000..a910bfb5bc --- /dev/null +++ b/wear/src/main/res/drawable/ic_action_add.xml @@ -0,0 +1,9 @@ + + + + diff --git a/wear/src/main/res/drawable/ic_action_minus.png b/wear/src/main/res/drawable/ic_action_minus.png deleted file mode 100644 index e68aed5a2f8985f44411ecbdc5a2fa7074c86f82..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 131 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTCFHaZ8kcwMxFCXM&P!M1~_~m}d z77jswwGFIilrv|aWCbcg1`l!%#O1SoP(9Geh%C&&(6^1@ytJ!kYjBknNW#{;R diff --git a/wear/src/main/res/drawable/ic_action_minus.xml b/wear/src/main/res/drawable/ic_action_minus.xml new file mode 100644 index 0000000000..40b17dc531 --- /dev/null +++ b/wear/src/main/res/drawable/ic_action_minus.xml @@ -0,0 +1,8 @@ + + + diff --git a/wear/src/main/res/drawable/ic_cancel.xml b/wear/src/main/res/drawable/ic_cancel.xml new file mode 100644 index 0000000000..a922f972ec --- /dev/null +++ b/wear/src/main/res/drawable/ic_cancel.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/wear/src/main/res/drawable/ic_confirm.xml b/wear/src/main/res/drawable/ic_confirm.xml new file mode 100644 index 0000000000..de281376b2 --- /dev/null +++ b/wear/src/main/res/drawable/ic_confirm.xml @@ -0,0 +1,8 @@ + + + diff --git a/wear/src/main/res/drawable/ic_icon.png b/wear/src/main/res/drawable/ic_icon.png deleted file mode 100644 index 584d65de70f6d1a23a376ded4666a876c469834c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3218 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 Ef-@R4=Kufz diff --git a/wear/src/main/res/drawable/ic_icon.xml b/wear/src/main/res/drawable/ic_icon.xml new file mode 100644 index 0000000000..ae7fa78499 --- /dev/null +++ b/wear/src/main/res/drawable/ic_icon.xml @@ -0,0 +1,16 @@ + + + + + + + + + + diff --git a/wear/src/main/res/drawable/ic_icon_snooze.png b/wear/src/main/res/drawable/ic_icon_snooze.png deleted file mode 100644 index 31b80685be1ddc6ae6e41d146641773bb06a122c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24861 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
  • WCP>YCs0-i346K*v=7@B;)D`5Cu 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 diff --git a/wear/src/main/res/drawable/ic_icon_snooze.xml b/wear/src/main/res/drawable/ic_icon_snooze.xml new file mode 100644 index 0000000000..15e6a5c105 --- /dev/null +++ b/wear/src/main/res/drawable/ic_icon_snooze.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + diff --git a/wear/src/main/res/drawable/loop_green_25.png b/wear/src/main/res/drawable/loop_green_25.png deleted file mode 100644 index 37076d5577c90d853bd24ec600a7f91fb10cef00..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21623 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 NPIj|xvuylU{~Nk!O#T1> diff --git a/wear/src/main/res/drawable/loop_green_25.xml b/wear/src/main/res/drawable/loop_green_25.xml new file mode 100644 index 0000000000..8ee928194d --- /dev/null +++ b/wear/src/main/res/drawable/loop_green_25.xml @@ -0,0 +1,9 @@ + + + + diff --git a/wear/src/main/res/drawable/loop_grey_25.png b/wear/src/main/res/drawable/loop_grey_25.png deleted file mode 100644 index 781f68d17d7710e202d4ea655f4d8869a262a70d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 22321 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 D%90hr diff --git a/wear/src/main/res/drawable/loop_grey_25.xml b/wear/src/main/res/drawable/loop_grey_25.xml new file mode 100644 index 0000000000..34a7a80b72 --- /dev/null +++ b/wear/src/main/res/drawable/loop_grey_25.xml @@ -0,0 +1,9 @@ + + + + diff --git a/wear/src/main/res/drawable/loop_red_25.png b/wear/src/main/res/drawable/loop_red_25.png deleted file mode 100644 index e9dcdb0da310eb40299d50126dda5a528c8fdef2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21623 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 I%5Uv|05$MU?*IS* diff --git a/wear/src/main/res/drawable/loop_red_25.xml b/wear/src/main/res/drawable/loop_red_25.xml new file mode 100644 index 0000000000..688ff02e24 --- /dev/null +++ b/wear/src/main/res/drawable/loop_red_25.xml @@ -0,0 +1,9 @@ + + + + diff --git a/wear/src/main/res/drawable/settings_off.xml b/wear/src/main/res/drawable/settings_off.xml new file mode 100644 index 0000000000..bbe06c1740 --- /dev/null +++ b/wear/src/main/res/drawable/settings_off.xml @@ -0,0 +1,10 @@ + + + diff --git a/wear/src/main/res/drawable/settings_on.xml b/wear/src/main/res/drawable/settings_on.xml new file mode 100644 index 0000000000..b63a5fba59 --- /dev/null +++ b/wear/src/main/res/drawable/settings_on.xml @@ -0,0 +1,10 @@ + + + From 88072ea752348022ef137ed616d90d86a6b9cc4b Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 1 Jul 2022 11:36:28 +0200 Subject: [PATCH 14/63] RFSpyReader -> kt --- .../pump/medtronic/MedtronicPumpPlugin.kt | 17 +-- .../common/hw/rileylink/ble/RFSpyReader.java | 127 ------------------ .../common/hw/rileylink/ble/RFSpyReader.kt | 98 ++++++++++++++ 3 files changed, 102 insertions(+), 140 deletions(-) delete mode 100644 rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.java create mode 100644 rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.kt diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt index 01ff035702..ba19c40278 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt @@ -20,6 +20,7 @@ import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification import info.nightscout.androidaps.plugins.pump.common.PumpPluginAbstract +import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.plugins.pump.common.events.EventRefreshButtonState @@ -54,8 +55,6 @@ import info.nightscout.androidaps.plugins.pump.medtronic.util.MedtronicUtil.Comp import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.FabricPrivacy import info.nightscout.androidaps.utils.TimeChangeType -import info.nightscout.androidaps.interfaces.ResourceHelper -import info.nightscout.androidaps.plugins.pump.common.data.PumpStatus import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag @@ -306,12 +305,8 @@ class MedtronicPumpPlugin @Inject constructor( private val isPumpNotReachable: Boolean get() { val rileyLinkServiceState = rileyLinkServiceData.rileyLinkServiceState - if (rileyLinkServiceState == null) { - aapsLogger.debug(LTag.PUMP, "RileyLink unreachable. RileyLinkServiceState is null.") - return false - } - if (rileyLinkServiceState != RileyLinkServiceState.PumpConnectorReady // - && rileyLinkServiceState != RileyLinkServiceState.RileyLinkReady // + if (rileyLinkServiceState != RileyLinkServiceState.PumpConnectorReady + && rileyLinkServiceState != RileyLinkServiceState.RileyLinkReady && rileyLinkServiceState != RileyLinkServiceState.TuneUpDevice ) { aapsLogger.debug(LTag.PUMP, "RileyLink unreachable.") @@ -998,11 +993,7 @@ class MedtronicPumpPlugin @Inject constructor( } @Synchronized - private fun workWithStatusRefresh( - action: StatusRefreshAction, // - statusRefreshType: MedtronicStatusRefreshType?, // - time: Long? - ): Map? { + private fun workWithStatusRefresh(action: StatusRefreshAction, statusRefreshType: MedtronicStatusRefreshType?, time: Long?): Map? { return when (action) { StatusRefreshAction.Add -> { statusRefreshMap[statusRefreshType!!] = time!! diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.java b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.java deleted file mode 100644 index 9e3a094a9c..0000000000 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.java +++ /dev/null @@ -1,127 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble; - -import android.os.SystemClock; - -import java.util.UUID; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.Semaphore; -import java.util.concurrent.TimeUnit; - -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkEncodingType; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.BLECommOperationResult; -import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.common.utils.ThreadUtil; -import info.nightscout.shared.logging.AAPSLogger; -import info.nightscout.shared.logging.LTag; - -/** - * Created by geoff on 5/26/16. - */ -public class RFSpyReader { - - private final AAPSLogger aapsLogger; - ExecutorService executor = Executors.newSingleThreadExecutor(); - private final RileyLinkBLE rileyLinkBle; - private final Semaphore waitForRadioData = new Semaphore(0, true); - private final LinkedBlockingQueue mDataQueue = new LinkedBlockingQueue<>(); - private int acquireCount = 0; - private int releaseCount = 0; - private boolean stopAtNull = true; - - - RFSpyReader(AAPSLogger aapsLogger, RileyLinkBLE rileyLinkBle) { - this.aapsLogger = aapsLogger; - this.rileyLinkBle = rileyLinkBle; - } - - - void setRileyLinkEncodingType(RileyLinkEncodingType encodingType) { - aapsLogger.debug("setRileyLinkEncodingType: " + encodingType); - stopAtNull = !(encodingType == RileyLinkEncodingType.Manchester || // - encodingType == RileyLinkEncodingType.FourByteSixByteRileyLink); - } - - - // This timeout must be coordinated with the length of the RFSpy radio operation or Bad Things Happen. - byte[] poll(int timeout_ms) { - aapsLogger.debug(LTag.PUMPBTCOMM, ThreadUtil.sig() + "Entering poll at t==" + SystemClock.uptimeMillis() + ", timeout is " + timeout_ms - + " mDataQueue size is " + mDataQueue.size()); - - if (mDataQueue.isEmpty()) { - try { - // block until timeout or data available. - // returns null if timeout. - byte[] dataFromQueue = mDataQueue.poll(timeout_ms, TimeUnit.MILLISECONDS); - if (dataFromQueue != null) { - aapsLogger.debug(LTag.PUMPBTCOMM, "Got data [" + ByteUtil.shortHexString(dataFromQueue) + "] at t==" - + SystemClock.uptimeMillis()); - } else { - aapsLogger.debug(LTag.PUMPBTCOMM, "Got data [null] at t==" + SystemClock.uptimeMillis()); - } - return dataFromQueue; - } catch (InterruptedException e) { - aapsLogger.error(LTag.PUMPBTCOMM, "poll: Interrupted waiting for data"); - } - } - - return null; - } - - - // Call this from the "response count" notification handler. - void newDataIsAvailable() { - releaseCount++; - - aapsLogger.debug(LTag.PUMPBTCOMM, ThreadUtil.sig() + "waitForRadioData released(count=" + releaseCount + ") at t=" - + SystemClock.uptimeMillis()); - waitForRadioData.release(); - } - - - public void start() { - executor.execute(() -> { - UUID serviceUUID = UUID.fromString(GattAttributes.SERVICE_RADIO); - UUID radioDataUUID = UUID.fromString(GattAttributes.CHARA_RADIO_DATA); - BLECommOperationResult result; - //noinspection InfiniteLoopStatement - while (true) { - try { - acquireCount++; - waitForRadioData.acquire(); - aapsLogger.debug(LTag.PUMPBTCOMM, ThreadUtil.sig() + "waitForRadioData acquired (count=" + acquireCount + ") at t=" - + SystemClock.uptimeMillis()); - SystemClock.sleep(100); - SystemClock.sleep(1); - result = rileyLinkBle.readCharacteristicBlocking(serviceUUID, radioDataUUID); - SystemClock.sleep(100); - - if (result.resultCode == BLECommOperationResult.RESULT_SUCCESS) { - if (stopAtNull) { - // only data up to the first null is valid - for (int i = 0; i < result.value.length; i++) { - if (result.value[i] == 0) { - result.value = ByteUtil.substring(result.value, 0, i); - break; - } - } - } - mDataQueue.add(result.value); - } else if (result.resultCode == BLECommOperationResult.RESULT_INTERRUPTED) { - aapsLogger.error(LTag.PUMPBTCOMM, "Read operation was interrupted"); - } else if (result.resultCode == BLECommOperationResult.RESULT_TIMEOUT) { - aapsLogger.error(LTag.PUMPBTCOMM, "Read operation on Radio Data timed out"); - } else if (result.resultCode == BLECommOperationResult.RESULT_BUSY) { - aapsLogger.error(LTag.PUMPBTCOMM, "FAIL: RileyLinkBLE reports operation already in progress"); - } else if (result.resultCode == BLECommOperationResult.RESULT_NONE) { - aapsLogger.error(LTag.PUMPBTCOMM, "FAIL: got invalid result code: " + result.resultCode); - } - } catch (InterruptedException e) { - aapsLogger.error(LTag.PUMPBTCOMM, "Interrupted while waiting for data"); - } - } - }); - } -} diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.kt b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.kt new file mode 100644 index 0000000000..62abb3fd8e --- /dev/null +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/ble/RFSpyReader.kt @@ -0,0 +1,98 @@ +package info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble + +import android.os.SystemClock +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.GattAttributes +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkEncodingType +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.operations.BLECommOperationResult +import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil +import info.nightscout.androidaps.plugins.pump.common.utils.ThreadUtil +import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.logging.LTag +import java.util.* +import java.util.concurrent.Executors +import java.util.concurrent.LinkedBlockingQueue +import java.util.concurrent.Semaphore +import java.util.concurrent.TimeUnit + +/** + * Created by geoff on 5/26/16. + */ +class RFSpyReader internal constructor(private val aapsLogger: AAPSLogger, private val rileyLinkBle: RileyLinkBLE) { + + private var executor = Executors.newSingleThreadExecutor() + private val waitForRadioData = Semaphore(0, true) + private val mDataQueue = LinkedBlockingQueue() + private var acquireCount = 0 + private var releaseCount = 0 + private var stopAtNull = true + fun setRileyLinkEncodingType(encodingType: RileyLinkEncodingType) { + aapsLogger.debug("setRileyLinkEncodingType: $encodingType") + stopAtNull = !(encodingType == RileyLinkEncodingType.Manchester || encodingType == RileyLinkEncodingType.FourByteSixByteRileyLink) + } + + // This timeout must be coordinated with the length of the RFSpy radio operation or Bad Things Happen. + fun poll(timeout_ms: Int): ByteArray? { + aapsLogger.debug(LTag.PUMPBTCOMM, "${ThreadUtil.sig()}Entering poll at t==${SystemClock.uptimeMillis()}, timeout is $timeout_ms mDataQueue size is ${mDataQueue.size}") + if (mDataQueue.isEmpty()) { + try { + // block until timeout or data available. + // returns null if timeout. + val dataFromQueue = mDataQueue.poll(timeout_ms.toLong(), TimeUnit.MILLISECONDS) + if (dataFromQueue != null) + aapsLogger.debug(LTag.PUMPBTCOMM, "Got data [${ByteUtil.shortHexString(dataFromQueue)}] at t==${SystemClock.uptimeMillis()}") + else + aapsLogger.debug(LTag.PUMPBTCOMM, "Got data [null] at t==" + SystemClock.uptimeMillis()) + return dataFromQueue + } catch (e: InterruptedException) { + aapsLogger.error(LTag.PUMPBTCOMM, "poll: Interrupted waiting for data") + } + } + return null + } + + // Call this from the "response count" notification handler. + fun newDataIsAvailable() { + releaseCount++ + aapsLogger.debug(LTag.PUMPBTCOMM, "${ThreadUtil.sig()}waitForRadioData released(count=$releaseCount) at t=${SystemClock.uptimeMillis()}") + waitForRadioData.release() + } + + fun start() { + executor.execute { + val serviceUUID = UUID.fromString(GattAttributes.SERVICE_RADIO) + val radioDataUUID = UUID.fromString(GattAttributes.CHARA_RADIO_DATA) + var result: BLECommOperationResult + while (true) { + try { + acquireCount++ + waitForRadioData.acquire() + aapsLogger.debug(LTag.PUMPBTCOMM, "${ThreadUtil.sig()}waitForRadioData acquired (count=$acquireCount) at t=${SystemClock.uptimeMillis()}") + SystemClock.sleep(100) + result = rileyLinkBle.readCharacteristicBlocking(serviceUUID, radioDataUUID) + SystemClock.sleep(100) + if (result.resultCode == BLECommOperationResult.RESULT_SUCCESS) { + if (stopAtNull) { + // only data up to the first null is valid + for (i in result.value.indices) { + if (result.value[i].toInt() == 0) { + result.value = ByteUtil.substring(result.value, 0, i) + break + } + } + } + mDataQueue.add(result.value) + } else if (result.resultCode == BLECommOperationResult.RESULT_INTERRUPTED) + aapsLogger.error(LTag.PUMPBTCOMM, "Read operation was interrupted") + else if (result.resultCode == BLECommOperationResult.RESULT_TIMEOUT) + aapsLogger.error(LTag.PUMPBTCOMM, "Read operation on Radio Data timed out") + else if (result.resultCode == BLECommOperationResult.RESULT_BUSY) + aapsLogger.error(LTag.PUMPBTCOMM, "FAIL: RileyLinkBLE reports operation already in progress") + else if (result.resultCode == BLECommOperationResult.RESULT_NONE) + aapsLogger.error(LTag.PUMPBTCOMM, "FAIL: got invalid result code: ${result.resultCode}") + } catch (e: InterruptedException) { + aapsLogger.error(LTag.PUMPBTCOMM, "Interrupted while waiting for data") + } + } + } + } +} \ No newline at end of file From ad89d54319208ca58cf382021b5d2bdcf59b09e5 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 1 Jul 2022 12:38:05 +0200 Subject: [PATCH 15/63] MedtronicPumpPlugin -> kt --- .../pump/medtronic/MedtronicPumpPlugin.kt | 54 +++---------------- 1 file changed, 8 insertions(+), 46 deletions(-) diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt index ba19c40278..a3849304e5 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt @@ -201,9 +201,7 @@ class MedtronicPumpPlugin @Inject constructor( do { SystemClock.sleep(60000) if (this.isInitialized) { - val statusRefresh = workWithStatusRefresh( - StatusRefreshAction.GetData, null, null - )!! + val statusRefresh = synchronized(statusRefreshMap) { HashMap(statusRefreshMap) } if (doWeHaveAnyStatusNeededRefreshing(statusRefresh)) { if (!commandQueue.statusInQueue()) { commandQueue.readStatus(rh.gs(R.string.scheduled_status_refresh), null) @@ -316,10 +314,7 @@ class MedtronicPumpPlugin @Inject constructor( } private fun refreshAnyStatusThatNeedsToBeRefreshed() { - val statusRefresh = workWithStatusRefresh( - StatusRefreshAction.GetData, null, - null - )!! + val statusRefresh = synchronized(statusRefreshMap) { HashMap(statusRefreshMap) } if (!doWeHaveAnyStatusNeededRefreshing(statusRefresh)) { return } @@ -659,19 +654,9 @@ class MedtronicPumpPlugin @Inject constructor( @Suppress("SameParameterValue") private fun setNotReachable(isBolus: Boolean, success: Boolean): PumpEnactResult { setRefreshButtonEnabled(true) - if (isBolus) { - bolusDeliveryType = BolusDeliveryType.Idle - } - return if (success) { - PumpEnactResult(injector) // - .success(true) // - .enacted(false) - } else { - PumpEnactResult(injector) // - .success(false) // - .enacted(false) // - .comment(R.string.medtronic_pump_status_pump_unreachable) - } + if (isBolus) bolusDeliveryType = BolusDeliveryType.Idle + return if (success) PumpEnactResult(injector).success(true).enacted(false) + else PumpEnactResult(injector).success(false).enacted(false).comment(R.string.medtronic_pump_status_pump_unreachable) } override fun stopBolusDelivering() { @@ -688,7 +673,7 @@ class MedtronicPumpPlugin @Inject constructor( } // if enforceNew===true current temp basal is canceled and new TBR set (duration is prolonged), - // if false and the same rate is requested enacted=false and success=true is returned and TBR is not changed +// if false and the same rate is requested enacted=false and success=true is returned and TBR is not changed @Synchronized override fun setTempBasalAbsolute(absoluteRate: Double, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: TemporaryBasalType): PumpEnactResult { setRefreshButtonEnabled(false) @@ -975,38 +960,15 @@ class MedtronicPumpPlugin @Inject constructor( MedtronicStatusRefreshType.RemainingInsulin -> { val remaining = medtronicPumpStatus.reservoirRemainingUnits val min: Int = if (remaining > 50) 4 * 60 else if (remaining > 20) 60 else 15 - workWithStatusRefresh(StatusRefreshAction.Add, refreshType, getTimeInFutureFromMinutes(min)) + synchronized(statusRefreshMap) { statusRefreshMap[refreshType] = getTimeInFutureFromMinutes(min) } } MedtronicStatusRefreshType.PumpTime, MedtronicStatusRefreshType.Configuration, MedtronicStatusRefreshType.BatteryStatus, MedtronicStatusRefreshType.PumpHistory -> { - workWithStatusRefresh( - StatusRefreshAction.Add, refreshType, - getTimeInFutureFromMinutes(refreshType.refreshTime + additionalTimeInMinutes) - ) + synchronized(statusRefreshMap) { statusRefreshMap[refreshType] = getTimeInFutureFromMinutes(refreshType.refreshTime + additionalTimeInMinutes) } } } } - private enum class StatusRefreshAction { - Add, // - GetData - } - - @Synchronized - private fun workWithStatusRefresh(action: StatusRefreshAction, statusRefreshType: MedtronicStatusRefreshType?, time: Long?): Map? { - return when (action) { - StatusRefreshAction.Add -> { - statusRefreshMap[statusRefreshType!!] = time!! - null - } - - StatusRefreshAction.GetData -> { - HashMap(statusRefreshMap) - } - - } - } - private fun getTimeInFutureFromMinutes(minutes: Int): Long { return System.currentTimeMillis() + getTimeInMs(minutes) } From 53c041f5cfa465db8ce8da7711bf89468088612f Mon Sep 17 00:00:00 2001 From: Andy Rozman Date: Sun, 3 Jul 2022 15:34:33 +0100 Subject: [PATCH 16/63] - extended pump-common package a little, so that in the future we can abstract some of stuff that is used by all (most) of drivers: History Dialog, BLE_Discovery, events and some other stuff (I used this with my new Ypso driver and I want to use the same with Tslim) --- .../pump/medtronic/MedtronicPumpPlugin.kt | 10 +- .../medtronic/driver/MedtronicPumpStatus.kt | 2 +- pump-common/src/main/AndroidManifest.xml | 14 +- .../plugins/pump/common/PumpPluginAbstract.kt | 43 ++- .../pump/common/ble/BondStateReceiver.kt | 77 ++++ .../plugins/pump/common/data/PumpStatus.kt | 7 +- .../pump/common/data/PumpTimeDifferenceDto.kt | 25 ++ .../pump/common/defs/BasalProfileStatus.java | 14 + .../pump/common/defs/PumpDriverState.kt | 28 +- .../pump/common/defs/PumpHistoryEntryGroup.kt | 39 +- .../pump/common/defs/PumpRunningState.kt | 9 + .../pump/common/defs/PumpTypeGroupConfig.kt | 8 + .../common/defs/PumpUpdateFragmentType.kt | 49 +++ .../common/driver/PumpDriverConfiguration.kt | 11 + .../driver/PumpDriverConfigurationCapable.kt | 7 + .../pump/common/driver/ble/PumpBLESelector.kt | 105 ++++++ .../driver/ble/PumpBLESelectorAbstract.kt | 108 ++++++ .../driver/history/PumpDataConverter.kt | 4 + .../driver/history/PumpHistoryDataProvider.kt | 75 ++++ .../PumpHistoryDataProviderAbstract.kt | 46 +++ .../common/driver/history/PumpHistoryEntry.kt | 18 + .../pump/common/events/EventBondChanged.kt | 8 + .../pump/common/events/EventPumpChanged.kt | 8 + .../EventPumpConnectionParametersChanged.kt | 6 + .../events/EventPumpFragmentValuesChanged.kt | 14 + .../common/events/EventRefreshButtonState.kt | 0 .../pump/common/ui/PumpBLEConfigActivity.kt | 338 ++++++++++++++++++ .../pump/common/ui/PumpHistoryActivity.kt | 217 +++++++++++ .../res/layout/pump_ble_config_activity.xml | 82 +++++ .../res/layout/pump_ble_config_scan_item.xml | 24 ++ .../main/res/layout/pump_history_activity.xml | 67 ++++ .../src/main/res/layout/pump_history_item.xml | 32 ++ pump-common/src/main/res/values/strings.xml | 74 +++- pump-common/src/main/res/values/styles.xml | 18 + 34 files changed, 1549 insertions(+), 38 deletions(-) create mode 100644 pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ble/BondStateReceiver.kt create mode 100755 pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/PumpTimeDifferenceDto.kt create mode 100755 pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/BasalProfileStatus.java create mode 100755 pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpRunningState.kt create mode 100644 pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpTypeGroupConfig.kt create mode 100755 pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpUpdateFragmentType.kt create mode 100644 pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/PumpDriverConfiguration.kt create mode 100644 pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/PumpDriverConfigurationCapable.kt create mode 100644 pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/ble/PumpBLESelector.kt create mode 100644 pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/ble/PumpBLESelectorAbstract.kt create mode 100644 pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpDataConverter.kt create mode 100644 pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryDataProvider.kt create mode 100644 pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryDataProviderAbstract.kt create mode 100644 pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryEntry.kt create mode 100644 pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventBondChanged.kt create mode 100755 pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpChanged.kt create mode 100644 pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpConnectionParametersChanged.kt create mode 100755 pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpFragmentValuesChanged.kt rename {rileylink => pump-common}/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRefreshButtonState.kt (100%) mode change 100644 => 100755 create mode 100755 pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ui/PumpBLEConfigActivity.kt create mode 100755 pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ui/PumpHistoryActivity.kt create mode 100755 pump-common/src/main/res/layout/pump_ble_config_activity.xml create mode 100755 pump-common/src/main/res/layout/pump_ble_config_scan_item.xml create mode 100755 pump-common/src/main/res/layout/pump_history_activity.xml create mode 100755 pump-common/src/main/res/layout/pump_history_item.xml create mode 100644 pump-common/src/main/res/values/styles.xml diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt index a3849304e5..a0fb470863 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.kt @@ -194,7 +194,11 @@ class MedtronicPumpPlugin @Inject constructor( } } - override fun onStartCustomActions() { + override fun hasService(): Boolean { + return true + } + + override fun onStartScheduledPumpActions() { // check status every minute (if any status needs refresh we send readStatus command) Thread { @@ -673,7 +677,7 @@ class MedtronicPumpPlugin @Inject constructor( } // if enforceNew===true current temp basal is canceled and new TBR set (duration is prolonged), -// if false and the same rate is requested enacted=false and success=true is returned and TBR is not changed + // if false and the same rate is requested enacted=false and success=true is returned and TBR is not changed @Synchronized override fun setTempBasalAbsolute(absoluteRate: Double, durationInMinutes: Int, profile: Profile, enforceNew: Boolean, tbrType: TemporaryBasalType): PumpEnactResult { setRefreshButtonEnabled(false) @@ -743,7 +747,7 @@ class MedtronicPumpPlugin @Inject constructor( PumpEnactResult(injector).success(false).enacted(false) // .comment(R.string.medtronic_cmd_tbr_could_not_be_delivered) } else { - medtronicPumpStatus.tempBasalStart = Date() + medtronicPumpStatus.tempBasalStart = System.currentTimeMillis() medtronicPumpStatus.tempBasalAmount = absoluteRate medtronicPumpStatus.tempBasalLength = durationInMinutes diff --git a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/driver/MedtronicPumpStatus.kt b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/driver/MedtronicPumpStatus.kt index 504994800f..82238a9e3f 100644 --- a/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/driver/MedtronicPumpStatus.kt +++ b/medtronic/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/driver/MedtronicPumpStatus.kt @@ -122,7 +122,7 @@ class MedtronicPumpStatus @Inject constructor(private val rh: ResourceHelper, get() { if (tempBasalStart == null) return null if (tempBasalEnd == null) { - val startTime = tempBasalStart!!.time + val startTime = tempBasalStart!! tempBasalEnd = startTime + tempBasalLength!! * 60 * 1000 } if (System.currentTimeMillis() > tempBasalEnd!!) { diff --git a/pump-common/src/main/AndroidManifest.xml b/pump-common/src/main/AndroidManifest.xml index b935efb489..84d3bd3279 100644 --- a/pump-common/src/main/AndroidManifest.xml +++ b/pump-common/src/main/AndroidManifest.xml @@ -1,6 +1,18 @@ - + + + + + + + + + diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.kt index 00ee367a8c..b955024616 100644 --- a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.kt +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/PumpPluginAbstract.kt @@ -4,6 +4,7 @@ import android.content.Context import android.content.Intent import android.content.ServiceConnection import android.text.format.DateFormat +import com.google.gson.GsonBuilder import dagger.android.HasAndroidInjector import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.PumpEnactResult @@ -25,7 +26,6 @@ import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DecimalFormatter.to0Decimal import info.nightscout.androidaps.utils.DecimalFormatter.to2Decimal import info.nightscout.androidaps.utils.FabricPrivacy -import info.nightscout.androidaps.interfaces.ResourceHelper import info.nightscout.androidaps.utils.rx.AapsSchedulers import info.nightscout.shared.logging.AAPSLogger import info.nightscout.shared.logging.LTag @@ -56,7 +56,7 @@ abstract class PumpPluginAbstract protected constructor( var pumpSyncStorage: info.nightscout.androidaps.plugins.pump.common.sync.PumpSyncStorage ) : PumpPluginBase(pluginDescription!!, injector!!, aapsLogger, rh, commandQueue), Pump, Constraints, info.nightscout.androidaps.plugins.pump.common.sync.PumpSyncEntriesCreator { - private val disposable = CompositeDisposable() + val disposable = CompositeDisposable() // Pump capabilities final override var pumpDescription = PumpDescription() @@ -68,30 +68,41 @@ abstract class PumpPluginAbstract protected constructor( protected var displayConnectionMessages = false var pumpType: PumpType = PumpType.GENERIC_AAPS + get() = field set(value) { field = value pumpDescription.fillFor(value) } + protected var gson = GsonBuilder().excludeFieldsWithoutExposeAnnotation().create() + abstract fun initPumpStatusData() + open fun hasService(): Boolean { + return true + } + override fun onStart() { super.onStart() initPumpStatusData() - val intent = Intent(context, serviceClass) - context.bindService(intent, serviceConnection!!, Context.BIND_AUTO_CREATE) + if (hasService()) { + val intent = Intent(context, serviceClass) + context.bindService(intent, serviceConnection!!, Context.BIND_AUTO_CREATE) + disposable.add(rxBus + .toObservable(EventAppExit::class.java) + .observeOn(aapsSchedulers.io) + .subscribe({ _ -> context.unbindService(serviceConnection!!) }) { throwable: Throwable? -> fabricPrivacy.logException(throwable!!) } + ) + } serviceRunning = true - disposable.add(rxBus - .toObservable(EventAppExit::class.java) - .observeOn(aapsSchedulers.io) - .subscribe({ _ -> context.unbindService(serviceConnection!!) }) { throwable: Throwable? -> fabricPrivacy.logException(throwable!!) } - ) - onStartCustomActions() + onStartScheduledPumpActions() } override fun onStop() { - aapsLogger.debug(LTag.PUMP, deviceID() + " onStop()") - context.unbindService(serviceConnection!!) + aapsLogger.debug(LTag.PUMP, model().model + " onStop()") + if (hasService()) { + context.unbindService(serviceConnection!!) + } serviceRunning = false disposable.clear() super.onStop() @@ -100,7 +111,7 @@ abstract class PumpPluginAbstract protected constructor( /** * If we need to run any custom actions in onStart (triggering events, etc) */ - abstract fun onStartCustomActions() + abstract fun onStartScheduledPumpActions() /** * Service class (same one you did serviceConnection for) @@ -231,7 +242,8 @@ abstract class PumpPluginAbstract protected constructor( val extended = JSONObject() try { battery.put("percent", pumpStatusData.batteryRemaining) - status.put("status", pumpStatusData.pumpStatusType.status) +// TODO check this status.put("status", pumpStatusData.pumpStatusType.status) + status.put("status", pumpStatusData.pumpRunningState.status) extended.put("Version", version) try { extended.put("ActiveProfile", profileName) @@ -324,6 +336,7 @@ abstract class PumpPluginAbstract protected constructor( // bolus needed, ask pump to deliver it deliverBolus(detailedBolusInfo) } else { + detailedBolusInfo.timestamp = System.currentTimeMillis() // no bolus required, carb only treatment pumpSyncStorage.addCarbs(PumpDbEntryCarbs(detailedBolusInfo, this)) @@ -360,4 +373,4 @@ abstract class PumpPluginAbstract protected constructor( pumpDescription.fillFor(pumpType) this.pumpType = pumpType } -} \ No newline at end of file +} diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ble/BondStateReceiver.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ble/BondStateReceiver.kt new file mode 100644 index 0000000000..37df0f9e0c --- /dev/null +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ble/BondStateReceiver.kt @@ -0,0 +1,77 @@ +package info.nightscout.androidaps.plugins.pump.common.ble + +import android.bluetooth.BluetoothDevice +import android.content.Context +import android.content.Intent +import androidx.annotation.StringRes +import com.google.gson.Gson +import dagger.android.DaggerBroadcastReceiver +import info.nightscout.androidaps.plugins.bus.RxBus +import info.nightscout.androidaps.plugins.pump.common.events.EventPumpConnectionParametersChanged +import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.logging.LTag +import info.nightscout.shared.sharedPreferences.SP +import javax.inject.Inject + +class BondStateReceiver( + @StringRes var deviceAddress: Int, + @StringRes var bondedFlag: Int, + var targetDevice: String, + var targetState: Int +) : DaggerBroadcastReceiver() { + + @Inject lateinit var sp: SP + @Inject lateinit var context: Context + @Inject lateinit var rh: ResourceHelper + @Inject lateinit var aapsLogger: AAPSLogger + @Inject lateinit var rxBus: RxBus + + var TAG = LTag.PUMPBTCOMM + var gson = Gson() + var applicationContext: Context? = null + + override fun onReceive(context: Context, intent: Intent) { + super.onReceive(context, intent) + val action = intent.action + val device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE) + aapsLogger.info(TAG, "in onReceive: INTENT" + gson.toJson(intent)) + if (device == null) { + aapsLogger.error(TAG, "onReceive. Device is null. Exiting.") + return + } else { + if (device.address != targetDevice) { + aapsLogger.error(TAG, "onReceive. Device is not the same as targetDevice. Exiting.") + return + } + } + + // Check if action is valid + if (action == null) return + + // Take action depending on new bond state + if (action == BluetoothDevice.ACTION_BOND_STATE_CHANGED) { + val bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR) + val previousBondState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, -1) + aapsLogger.info(TAG, "in onReceive: bondState=$bondState, previousBondState=$previousBondState") + if (bondState == targetState) { + aapsLogger.info(TAG, "onReceive: found targeted state: $targetState") + val currentDeviceSettings = sp.getString(deviceAddress, "") + if (currentDeviceSettings.equals(targetDevice)) { + if (targetState == 12) { + sp.putBoolean(bondedFlag, true) + rxBus.send(EventPumpConnectionParametersChanged()) + } else if (targetState == 10) { + sp.putBoolean(bondedFlag, false) + rxBus.send(EventPumpConnectionParametersChanged()) + } + context.unregisterReceiver(this) + } else { + aapsLogger.error(TAG, "onReceive: Device stored in SP is not the same as target device, process interrupted") + } + } else { + aapsLogger.info(TAG, "onReceive: currentBondState=$bondState, targetBondState=$targetState") + } + } + } +} \ No newline at end of file diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/PumpStatus.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/PumpStatus.kt index 9ecd30bca7..9c4ea272d9 100644 --- a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/PumpStatus.kt +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/PumpStatus.kt @@ -1,6 +1,6 @@ package info.nightscout.androidaps.plugins.pump.common.data -import info.nightscout.androidaps.plugins.pump.common.defs.PumpStatusType +import info.nightscout.androidaps.plugins.pump.common.defs.PumpRunningState import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import java.util.* @@ -33,12 +33,13 @@ abstract class PumpStatus(var pumpType: PumpType) { var dailyTotalUnits: Double? = null var maxDailyTotalUnits: String? = null var units: String? = null // Constants.MGDL or Constants.MMOL - var pumpStatusType = PumpStatusType.Running + var pumpRunningState = PumpRunningState.Running var basalsByHour: DoubleArray? = null - var tempBasalStart: Date? = null + var tempBasalStart: Long? = null var tempBasalAmount: Double? = 0.0 var tempBasalLength: Int? = 0 var tempBasalEnd: Long? = null + var pumpTime: PumpTimeDifferenceDto? = null abstract fun initSettings() diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/PumpTimeDifferenceDto.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/PumpTimeDifferenceDto.kt new file mode 100755 index 0000000000..561967c714 --- /dev/null +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/data/PumpTimeDifferenceDto.kt @@ -0,0 +1,25 @@ +package info.nightscout.androidaps.plugins.pump.common.data + +import org.joda.time.DateTime +import org.joda.time.Seconds + +/** + * Created by andy on 28/05/2021. + */ +class PumpTimeDifferenceDto constructor(var localDeviceTime: DateTime, + var pumpTime: DateTime) { + + var timeDifference = 0 + + fun calculateDifference() { + val secondsBetween = Seconds.secondsBetween(localDeviceTime, pumpTime) + timeDifference = secondsBetween.seconds + + // val diff = localDeviceTime - pumpTime + // timeDifference = (diff / 1000.0).toInt() + } + + init { + calculateDifference() + } +} \ No newline at end of file diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/BasalProfileStatus.java b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/BasalProfileStatus.java new file mode 100755 index 0000000000..0d56ee4ef8 --- /dev/null +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/BasalProfileStatus.java @@ -0,0 +1,14 @@ +package info.nightscout.androidaps.plugins.pump.common.defs; + +/** + * Created by andy on 1/20/19. + */ + +public enum BasalProfileStatus { + + NotInitialized, // + ProfileOK, // + ProfileChanged, // + ; + +} diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpDriverState.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpDriverState.kt index f72163ce92..6f6124005d 100644 --- a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpDriverState.kt +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpDriverState.kt @@ -1,14 +1,26 @@ package info.nightscout.androidaps.plugins.pump.common.defs -enum class PumpDriverState { +import info.nightscout.androidaps.plugins.pump.common.R - NotInitialized, - Connecting, - Connected, - Initialized, - Ready, Busy, - Suspended; +// TODO there are 3 classes now, that do similar things, sort of, need to define exact rules: PumpDeviceState, PumpDriverState, PumpStatusState + +// TODO split this enum into 2 +enum class PumpDriverState(var resourceId: Int) { + + NotInitialized(R.string.pump_status_not_initialized), // this state should be set only when driver is created + Connecting(R.string.connecting), // + Connected(R.string.connected), // + Initialized(R.string.pump_status_initialized), // this is weird state that probably won't be used, since its more driver centric that communication centric + EncryptCommunication(R.string.pump_status_encrypt), // + Ready(R.string.pump_status_ready), + Busy(R.string.pump_status_busy), // + Suspended(R.string.pump_status_suspended), // + Sleeping(R.string.pump_status_sleeping), + ExecutingCommand(R.string.pump_status_executing_command), + Disconnecting(R.string.disconnecting), + Disconnected(R.string.disconnected), + ErrorCommunicatingWithPump(R.string.pump_status_error_comm); fun isConnected(): Boolean = this == Connected || this == Initialized || this == Busy || this == Suspended fun isInitialized(): Boolean = this == Initialized || this == Busy || this == Suspended -} \ No newline at end of file +} diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpHistoryEntryGroup.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpHistoryEntryGroup.kt index 4a98471dc4..189353809a 100644 --- a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpHistoryEntryGroup.kt +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpHistoryEntryGroup.kt @@ -2,7 +2,7 @@ package info.nightscout.androidaps.plugins.pump.common.defs import info.nightscout.androidaps.plugins.pump.common.R import info.nightscout.androidaps.interfaces.ResourceHelper -import java.util.* +import kotlin.streams.toList /** * This file was taken from GGC - GNU Gluco Control (ggc.sourceforge.net), application for diabetes @@ -11,9 +11,10 @@ import java.util.* * * Author: Andy {andy.rozman@gmail.com} */ -enum class PumpHistoryEntryGroup(val resourceId: Int) { +enum class PumpHistoryEntryGroup(val resourceId: Int, val pumpTypeGroupConfig: PumpTypeGroupConfig = PumpTypeGroupConfig.All) { All(R.string.history_group_all), + Base(R.string.history_group_base), Bolus(R.string.history_group_bolus), Basal(R.string.history_group_basal), Prime(R.string.history_group_prime), @@ -22,7 +23,14 @@ enum class PumpHistoryEntryGroup(val resourceId: Int) { Glucose(R.string.history_group_glucose), Notification(R.string.history_group_notification), Statistic(R.string.history_group_statistic), - Unknown(R.string.history_group_unknown); + Other(R.string.history_group_other), + Unknown(R.string.history_group_unknown), + + // Ypso + EventsOnly(R.string.history_group_events), + EventsNoStat(R.string.history_group_events_no_stat) + + ; var translated: String? = null private set @@ -33,9 +41,10 @@ enum class PumpHistoryEntryGroup(val resourceId: Int) { companion object { - private var translatedList: MutableList? = null + @JvmStatic private var translatedList: MutableList? = null - private fun doTranslation(rh: ResourceHelper) { + fun doTranslation(rh: ResourceHelper) { + if (translatedList != null) return translatedList = ArrayList() for (pumpHistoryEntryGroup in values()) { pumpHistoryEntryGroup.translated = rh.gs(pumpHistoryEntryGroup.resourceId) @@ -43,9 +52,27 @@ enum class PumpHistoryEntryGroup(val resourceId: Int) { } } + // FIXME this is just for Java compatibility reasons (can be removed when all drivers using it are in Kotlin - OmnipodEros still in java) fun getTranslatedList(rh: ResourceHelper): List { + return getTranslatedList(rh, PumpTypeGroupConfig.All) + } + + fun getTranslatedList(rh: ResourceHelper, pumpTypeGroupConfig: PumpTypeGroupConfig = PumpTypeGroupConfig.All): List { if (translatedList == null) doTranslation(rh) - return translatedList!! + + val outList: List + + if (pumpTypeGroupConfig == PumpTypeGroupConfig.All) { + outList = translatedList!!.stream() + .filter { pre -> pre.pumpTypeGroupConfig == PumpTypeGroupConfig.All } + .toList(); + } else { + outList = translatedList!!.stream() + .filter { pre -> (pre.pumpTypeGroupConfig == PumpTypeGroupConfig.All || pre.pumpTypeGroupConfig == pumpTypeGroupConfig) } + .toList(); + } + + return outList } } diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpRunningState.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpRunningState.kt new file mode 100755 index 0000000000..f9dcabbf98 --- /dev/null +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpRunningState.kt @@ -0,0 +1,9 @@ +package info.nightscout.androidaps.plugins.pump.common.defs + +// TODO there are 3 classes now, that do similar things, sort of, need to define exact rules: PumpDeviceState, PumpDriverState, PumpStatusState + +enum class PumpRunningState(val status: String) { + + Running("normal"), + Suspended("suspended"); +} \ No newline at end of file diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpTypeGroupConfig.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpTypeGroupConfig.kt new file mode 100644 index 0000000000..cc553c732f --- /dev/null +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpTypeGroupConfig.kt @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.pump.common.defs + +enum class PumpTypeGroupConfig { + All, + Medtronic, + OmnipodEros, + YpsoPump +} \ No newline at end of file diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpUpdateFragmentType.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpUpdateFragmentType.kt new file mode 100755 index 0000000000..0558597127 --- /dev/null +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/defs/PumpUpdateFragmentType.kt @@ -0,0 +1,49 @@ +package info.nightscout.androidaps.plugins.pump.common.defs + +import java.util.* + +enum class PumpUpdateFragmentType { + None, + PumpStatus, + DriverStatus, + Queue, + Bolus, + TBR, + ProfileChange, + TBRCount, + BolusCount, + TreatmentValues(Arrays.asList(Bolus, TBR, TBRCount, BolusCount, ProfileChange)), // Last Bolus, TBR, Profile Change, TBR Count, Bolus Count + Full, + Configuration, // Firmware, Errors + Battery, + Reservoir, + OtherValues(Arrays.asList(Battery, Reservoir)), // Battery, Reservoir + Custom_1, + Custom_2, + Custom_3, + Custom_4, + Custom_5, + Custom_6, + Custom_7, + Custom_8 + ; + + final var children: List? = null + + constructor() { + } + + constructor(children: List) { + this.children = children; + } + + fun isOptionIncluded(type: PumpUpdateFragmentType): Boolean { + if (this == type) + return true + else if (this.children != null && this.children!!.contains(type)) + return true; + + return false; + } + +} \ No newline at end of file diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/PumpDriverConfiguration.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/PumpDriverConfiguration.kt new file mode 100644 index 0000000000..c5f28a4645 --- /dev/null +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/PumpDriverConfiguration.kt @@ -0,0 +1,11 @@ +package info.nightscout.androidaps.plugins.pump.common.driver + +import info.nightscout.androidaps.plugins.pump.common.driver.history.PumpHistoryDataProvider + +interface PumpDriverConfiguration { + + fun getPumpBLESelector(): PumpBLESelector + + fun getPumpHistoryDataProvider(): PumpHistoryDataProvider + +} \ No newline at end of file diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/PumpDriverConfigurationCapable.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/PumpDriverConfigurationCapable.kt new file mode 100644 index 0000000000..3c8e66fde3 --- /dev/null +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/PumpDriverConfigurationCapable.kt @@ -0,0 +1,7 @@ +package info.nightscout.androidaps.plugins.pump.common.driver + +interface PumpDriverConfigurationCapable { + + fun getPumpDriverConfiguration(): PumpDriverConfiguration + +} \ No newline at end of file diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/ble/PumpBLESelector.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/ble/PumpBLESelector.kt new file mode 100644 index 0000000000..530c127a4e --- /dev/null +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/ble/PumpBLESelector.kt @@ -0,0 +1,105 @@ +package info.nightscout.androidaps.plugins.pump.common.driver + +import android.bluetooth.BluetoothDevice +import android.bluetooth.le.ScanFilter +import android.bluetooth.le.ScanSettings +import android.content.Context + +interface PumpBLESelector { + + /** + * Called on resume + */ + fun onResume() + + /** + * Called on destory + */ + fun onDestroy() + + /** + * This method is called when device is being removed (it can be empty if you don't need to do any special action, but if you + * have to unbound (for example), then this is method where to call it. For unbounding removeBond is available + */ + fun removeDevice(device: BluetoothDevice) + + /** + * Cleanup method after device was removed + */ + fun cleanupAfterDeviceRemoved() + + /** + * operations when scan failed + */ + fun onScanFailed(context: Context, errorCode: Int) + + /** + * operations when scan starts + */ + fun onStartLeDeviceScan(context: Context) + + /** + * operations when scan stops + */ + fun onStopLeDeviceScan(context: Context) + + /** + * operations when scan was stopped manualy (press on button) + */ + fun onManualStopLeDeviceScan(context: Context) + + /** + * operations when on non manual stop of scan (on timeout) + */ + fun onNonManualStopLeDeviceScan(context: Context) + + /** + * get Scan Filters + */ + fun getScanFilters(): List? + + /** + * get Scan Settings + */ + fun getScanSettings(): ScanSettings? + + /** + * filter device on search (for cases where we can't do it with Scan Filters + */ + fun filterDevice(device: BluetoothDevice): BluetoothDevice? + + /** + * operations when device selected + */ + fun onDeviceSelected(bluetoothDevice: BluetoothDevice, bleAddress: String, deviceName: String) + + /** + * If pump has no name, this name will be used + */ + fun getUnknownPumpName(): String + + /** + * get Address of Currently selected pump, empty string if none + */ + fun currentlySelectedPumpAddress(): String + + /** + * get Name of Currently selected pump, getUnknownPumpName() string if none + */ + fun currentlySelectedPumpName(): String + + /** + * Get Translation Text + */ + fun getText(key: PumpBLESelectorText): String + +} + +enum class PumpBLESelectorText { + SCAN_TITLE, + SELECTED_PUMP_TITLE, + REMOVE_TITLE, + REMOVE_TEXT, + NO_SELECTED_PUMP, + PUMP_CONFIGURATION +} diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/ble/PumpBLESelectorAbstract.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/ble/PumpBLESelectorAbstract.kt new file mode 100644 index 0000000000..872645fa30 --- /dev/null +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/ble/PumpBLESelectorAbstract.kt @@ -0,0 +1,108 @@ +package info.nightscout.androidaps.plugins.pump.common.driver.ble + +import android.bluetooth.BluetoothDevice +import android.bluetooth.le.ScanFilter +import android.bluetooth.le.ScanSettings +import android.content.Context +import android.widget.Toast +import info.nightscout.androidaps.plugins.bus.RxBus +import info.nightscout.androidaps.plugins.pump.common.R +import info.nightscout.androidaps.plugins.pump.common.driver.PumpBLESelector +import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.logging.LTag +import info.nightscout.shared.sharedPreferences.SP + +abstract class PumpBLESelectorAbstract constructor( + var resourceHelper: ResourceHelper, + var aapsLogger: AAPSLogger, + var sp: SP, + var rxBus: RxBus, + var context: Context +) : PumpBLESelector { + + protected val TAG = LTag.PUMPBTCOMM + + override fun getScanSettings(): ScanSettings? { + return ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build() + } + + override fun getScanFilters(): MutableList? { + return null + } + + override fun filterDevice(device: BluetoothDevice): BluetoothDevice? { + return device + } + + override fun onResume() { + } + + override fun onDestroy() { + } + + override fun removeDevice(device: BluetoothDevice) { + } + + override fun cleanupAfterDeviceRemoved() { + } + + override fun onManualStopLeDeviceScan(context: Context) { + } + + override fun onNonManualStopLeDeviceScan(context: Context) { + } + + //fun onDeviceSelected(bluetoothDevice: BluetoothDevice, bleAddress: String, deviceName: String) + + override fun onScanFailed(context: Context, errorCode: Int) { + Toast.makeText( + context, resourceHelper.gs(R.string.ble_config_scan_error, errorCode), + Toast.LENGTH_LONG + ).show() + } + + override fun onStartLeDeviceScan(context: Context) { + Toast.makeText(context, R.string.ble_config_scan_scanning, Toast.LENGTH_SHORT).show() + } + + override fun onStopLeDeviceScan(context: Context) { + Toast.makeText(context, R.string.ble_config_scan_finished, Toast.LENGTH_SHORT).show() + } + + protected fun removeBond(bluetoothDevice: BluetoothDevice): Boolean { + return try { + val method = bluetoothDevice.javaClass.getMethod("removeBond") + val resultObject = method.invoke(bluetoothDevice) + if (resultObject == null) { + aapsLogger.error(TAG, "ERROR: result object is null") + false + } else { + val result = resultObject as Boolean + if (result) { + aapsLogger.info(TAG, "Successfully removed bond") + } else { + aapsLogger.warn(TAG, "Bond was not removed") + } + result + } + } catch (e: Exception) { + aapsLogger.error(TAG, "ERROR: could not remove bond") + e.printStackTrace() + false + } + } + + protected fun getBondingStatusDescription(state: Int): String { + return if (state == 10) { + "BOND_NONE" + } else if (state == 11) { + "BOND_BONDING" + } else if (state == 12) { + "BOND_BONDED" + } else { + "UNKNOWN BOND STATUS ($state)" + } + } + +} \ No newline at end of file diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpDataConverter.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpDataConverter.kt new file mode 100644 index 0000000000..0c8c8d1b25 --- /dev/null +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpDataConverter.kt @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.pump.common.driver.history + +interface PumpDataConverter { +} \ No newline at end of file diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryDataProvider.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryDataProvider.kt new file mode 100644 index 0000000000..6f2389338e --- /dev/null +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryDataProvider.kt @@ -0,0 +1,75 @@ +package info.nightscout.androidaps.plugins.pump.common.driver.history + +import androidx.annotation.StringRes +import info.nightscout.androidaps.plugins.pump.common.R +import info.nightscout.androidaps.plugins.pump.common.defs.PumpHistoryEntryGroup + +interface PumpHistoryDataProvider { + + /** + * Get Data, specified with PumpHistoryPeriod + */ + fun getData(period: PumpHistoryPeriod): List + + /** + * Get Initial Period + */ + fun getInitialPeriod(): PumpHistoryPeriod + + /** + * Get InitialData + */ + fun getInitialData(): List + + /** + * Get Allowed Pump History Groups (for specific pump) + */ + fun getAllowedPumpHistoryGroups(): List + + /** + * Get Spinner Width in pixels (same as specifying 150dp) + */ + fun getSpinnerWidthInPixels(): Int + + /** + * Get Translation Text + */ + fun getText(key: PumpHistoryText): String + + /** + * For filtering of items + */ + fun isItemInSelection(itemGroup: PumpHistoryEntryGroup, targetGroup: PumpHistoryEntryGroup): Boolean + +} + +enum class PumpHistoryPeriod constructor( + @StringRes var stringId: Int, + var isHours: Boolean = false +) { + + TODAY(R.string.time_today), + LAST_HOUR(R.string.time_last_hour, true), + LAST_3_HOURS(R.string.time_last_3_hours, true), + LAST_6_HOURS(R.string.time_last_6_hours, true), + LAST_12_HOURS(R.string.time_last_12_hours, true), + LAST_2_DAYS(R.string.time_last_2_days), + LAST_4_DAYS(R.string.time_last_4_days), + LAST_WEEK(R.string.time_last_week), + LAST_MONTH(R.string.time_last_month), + ALL(R.string.history_group_all) + +} + +enum class PumpHistoryText { + + PUMP_HISTORY, + + // OLD ONES + SCAN_TITLE, + SELECTED_PUMP_TITLE, + REMOVE_TITLE, + REMOVE_TEXT, + NO_SELECTED_PUMP, + PUMP_CONFIGURATION +} diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryDataProviderAbstract.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryDataProviderAbstract.kt new file mode 100644 index 0000000000..53dbbc0aba --- /dev/null +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryDataProviderAbstract.kt @@ -0,0 +1,46 @@ +package info.nightscout.androidaps.plugins.pump.common.driver.history + +import info.nightscout.androidaps.plugins.pump.common.defs.PumpHistoryEntryGroup +import java.util.* + +abstract class PumpHistoryDataProviderAbstract : PumpHistoryDataProvider { + + override fun getInitialData(): List { + return getData(getInitialPeriod()); + } + + override fun getSpinnerWidthInPixels(): Int { + return 150 + } + + protected fun getStartingTimeForData(period: PumpHistoryPeriod): Long { + val gregorianCalendar = GregorianCalendar() + + if (!period.isHours) { + gregorianCalendar.set(Calendar.HOUR_OF_DAY, 0) + gregorianCalendar.set(Calendar.MINUTE, 0) + gregorianCalendar.set(Calendar.SECOND, 0) + gregorianCalendar.set(Calendar.MILLISECOND, 0) + } + + when (period) { + PumpHistoryPeriod.TODAY -> return gregorianCalendar.timeInMillis + PumpHistoryPeriod.ALL -> return 0L + PumpHistoryPeriod.LAST_2_DAYS -> gregorianCalendar.add(Calendar.DAY_OF_MONTH, -1) + PumpHistoryPeriod.LAST_4_DAYS -> gregorianCalendar.add(Calendar.DAY_OF_MONTH, -3) + PumpHistoryPeriod.LAST_WEEK -> gregorianCalendar.add(Calendar.WEEK_OF_YEAR, -1) + PumpHistoryPeriod.LAST_MONTH -> gregorianCalendar.add(Calendar.MONTH, -1) + PumpHistoryPeriod.LAST_HOUR -> gregorianCalendar.add(Calendar.HOUR_OF_DAY, -1) + PumpHistoryPeriod.LAST_3_HOURS -> gregorianCalendar.add(Calendar.HOUR_OF_DAY, -3) + PumpHistoryPeriod.LAST_6_HOURS -> gregorianCalendar.add(Calendar.HOUR_OF_DAY, -6) + PumpHistoryPeriod.LAST_12_HOURS -> gregorianCalendar.add(Calendar.HOUR_OF_DAY, -12) + } + + return gregorianCalendar.timeInMillis + } + + override fun isItemInSelection(itemGroup: PumpHistoryEntryGroup, targetGroup: PumpHistoryEntryGroup): Boolean { + return itemGroup === targetGroup + } + +} \ No newline at end of file diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryEntry.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryEntry.kt new file mode 100644 index 0000000000..02e4e91b4c --- /dev/null +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/driver/history/PumpHistoryEntry.kt @@ -0,0 +1,18 @@ +package info.nightscout.androidaps.plugins.pump.common.driver.history + +import info.nightscout.androidaps.plugins.pump.common.defs.PumpHistoryEntryGroup +import info.nightscout.androidaps.interfaces.ResourceHelper + +interface PumpHistoryEntry { + + fun prepareEntryData(resourceHelper: ResourceHelper, pumpDataConverter: PumpDataConverter) + + fun getEntryDateTime(): String + + fun getEntryType(): String + + fun getEntryValue(): String + + fun getEntryTypeGroup(): PumpHistoryEntryGroup + +} \ No newline at end of file diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventBondChanged.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventBondChanged.kt new file mode 100644 index 0000000000..8e2c8b978c --- /dev/null +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventBondChanged.kt @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.pump.common.events + +import info.nightscout.androidaps.events.Event + +class EventBondChanged( + var connectionAddress: String, + var bondStatus: Boolean +) : Event() diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpChanged.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpChanged.kt new file mode 100755 index 0000000000..36b1107882 --- /dev/null +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpChanged.kt @@ -0,0 +1,8 @@ +package info.nightscout.androidaps.plugins.pump.common.events + +import info.nightscout.androidaps.events.Event + +class EventPumpChanged(var serialNumber: String, + var connectionAddress: String, + var parameters: MutableMap? = null) : Event() { +} \ No newline at end of file diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpConnectionParametersChanged.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpConnectionParametersChanged.kt new file mode 100644 index 0000000000..d6c5b1563a --- /dev/null +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpConnectionParametersChanged.kt @@ -0,0 +1,6 @@ +package info.nightscout.androidaps.plugins.pump.common.events + +import info.nightscout.androidaps.events.Event + +class EventPumpConnectionParametersChanged : Event() { +} \ No newline at end of file diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpFragmentValuesChanged.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpFragmentValuesChanged.kt new file mode 100755 index 0000000000..fcb55dcd11 --- /dev/null +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventPumpFragmentValuesChanged.kt @@ -0,0 +1,14 @@ +package info.nightscout.androidaps.plugins.pump.common.events + +import info.nightscout.androidaps.events.Event +import info.nightscout.androidaps.plugins.pump.common.defs.PumpUpdateFragmentType + +class EventPumpFragmentValuesChanged : Event { + + var updateType: PumpUpdateFragmentType = PumpUpdateFragmentType.None + + constructor(updateType: PumpUpdateFragmentType) { + this.updateType = updateType + } + +} \ No newline at end of file diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRefreshButtonState.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRefreshButtonState.kt old mode 100644 new mode 100755 similarity index 100% rename from rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRefreshButtonState.kt rename to pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRefreshButtonState.kt diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ui/PumpBLEConfigActivity.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ui/PumpBLEConfigActivity.kt new file mode 100755 index 0000000000..6333af2cc2 --- /dev/null +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ui/PumpBLEConfigActivity.kt @@ -0,0 +1,338 @@ +package info.nightscout.androidaps.plugins.pump.common.ui + +import android.annotation.SuppressLint +import android.bluetooth.BluetoothAdapter +import android.bluetooth.BluetoothDevice +import android.bluetooth.BluetoothManager +import android.bluetooth.le.BluetoothLeScanner +import android.bluetooth.le.ScanCallback +import android.bluetooth.le.ScanFilter +import android.bluetooth.le.ScanResult +import android.bluetooth.le.ScanSettings +import android.content.Context +import android.os.Bundle +import android.os.Handler +import android.os.HandlerThread +import android.view.MenuItem +import android.view.View +import android.view.ViewGroup +import android.widget.AdapterView +import android.widget.AdapterView.OnItemClickListener +import android.widget.BaseAdapter +import android.widget.TextView +import dagger.android.support.DaggerAppCompatActivity +import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.plugins.bus.RxBus +import info.nightscout.androidaps.plugins.pump.common.R +import info.nightscout.androidaps.plugins.pump.common.ble.BlePreCheck +import info.nightscout.androidaps.plugins.pump.common.databinding.PumpBleConfigActivityBinding +import info.nightscout.androidaps.plugins.pump.common.driver.PumpBLESelector +import info.nightscout.androidaps.plugins.pump.common.driver.PumpBLESelectorText +import info.nightscout.androidaps.plugins.pump.common.driver.PumpDriverConfigurationCapable +import info.nightscout.androidaps.utils.alertDialogs.OKDialog +import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.logging.LTag +import info.nightscout.shared.sharedPreferences.SP +import org.apache.commons.lang3.StringUtils +import javax.inject.Inject + +@SuppressLint("MissingPermission") +class PumpBLEConfigActivity : DaggerAppCompatActivity() { + + @Inject lateinit var resourceHelper: ResourceHelper + @Inject lateinit var activePlugin: ActivePlugin + @Inject lateinit var sp: SP + @Inject lateinit var blePreCheck: BlePreCheck + @Inject lateinit var context: Context + @Inject lateinit var aapsLogger: AAPSLogger + @Inject lateinit var rxBus: RxBus + + private lateinit var binding: PumpBleConfigActivityBinding + private lateinit var bleSelector: PumpBLESelector + + private var settings: ScanSettings? = null + private var filters: List? = null + private var bleScanner: BluetoothLeScanner? = null + private var deviceListAdapter = LeDeviceListAdapter() + private val handler = Handler(HandlerThread(this::class.simpleName + "Handler").also { it.start() }.looper) + private val bluetoothAdapter: BluetoothAdapter? get() = (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter + var scanning = false + private val devicesMap: MutableMap = HashMap() + + private val stopScanAfterTimeoutRunnable = Runnable { + if (scanning) { + stopLeDeviceScan(false) + } + } + + @SuppressLint("MissingPermission") + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = PumpBleConfigActivityBinding.inflate(layoutInflater) + setContentView(binding.root) + + if (!blePreCheck.prerequisitesCheck(this)) { + aapsLogger.error(TAG, "prerequisitesCheck failed.") + finish() + return + } + + // Configuration + val activePump = activePlugin.activePump + + if (activePump is PumpDriverConfigurationCapable) { + bleSelector = activePump.getPumpDriverConfiguration().getPumpBLESelector() + } else { + throw RuntimeException("PumpBLEConfigActivity can be used only with PumpDriverConfigurationCapable pump driver.") + } + + binding.pumpBleConfigCurrentlySelectedText.text = bleSelector.getText(PumpBLESelectorText.SELECTED_PUMP_TITLE) + binding.pumpBleConfigScanTitle.text = bleSelector.getText(PumpBLESelectorText.SCAN_TITLE) + + title = bleSelector.getText(PumpBLESelectorText.PUMP_CONFIGURATION) + supportActionBar?.setDisplayHomeAsUpEnabled(true) + supportActionBar?.setDisplayShowHomeEnabled(true) + + binding.pumpBleConfigScanDeviceList.adapter = deviceListAdapter + binding.pumpBleConfigScanDeviceList.onItemClickListener = OnItemClickListener { _: AdapterView<*>?, view: View, _: Int, _: Long -> + // stop scanning if still active + if (scanning) { + stopLeDeviceScan(true) + } + val bleAddress = (view.findViewById(R.id.pump_ble_config_scan_item_device_address) as TextView).text.toString() + val deviceName = (view.findViewById(R.id.pump_ble_config_scan_item_device_name) as TextView).text.toString() + + if (devicesMap.containsKey(bleAddress)) { + aapsLogger.debug(TAG, "Device FOUND in deviceMap: $bleAddress") + val bluetoothDevice = devicesMap[bleAddress] + bleSelector.onDeviceSelected(bluetoothDevice!!, bleAddress, deviceName) + } else { + aapsLogger.debug(TAG, "Device NOT found in deviceMap: $bleAddress") + } + + finish() + } + binding.pumpBleConfigScanStart.setOnClickListener { startLeDeviceScan() } + binding.pumpBleConfigButtonScanStop.setOnClickListener { + if (scanning) { + stopLeDeviceScan(true) + } + } + + binding.pumpBleConfigButtonRemove.setOnClickListener { + OKDialog.showConfirmation( + this@PumpBLEConfigActivity, + bleSelector.getText(PumpBLESelectorText.REMOVE_TITLE), + bleSelector.getText(PumpBLESelectorText.REMOVE_TEXT), + Runnable { + val deviceAddress: String = binding.pumpBleConfigCurrentlySelectedPumpAddress.text.toString() + aapsLogger.debug(TAG, "Removing device as selected: $deviceAddress") + if (devicesMap.containsKey(deviceAddress)) { + val bluetoothDevice = devicesMap[deviceAddress] + aapsLogger.debug(TAG, "Device can be detected near, so trying to remove bond if possible.") + bleSelector.removeDevice(bluetoothDevice!!) + } else { + val remoteDevice = bluetoothAdapter!!.getRemoteDevice(deviceAddress) + if (remoteDevice != null) { + bleSelector.removeDevice(remoteDevice) + } + } + bleSelector.cleanupAfterDeviceRemoved() + updateCurrentlySelectedBTDevice() + }) + } + } + + private fun updateCurrentlySelectedBTDevice() { + val address = bleSelector.currentlySelectedPumpAddress() + if (StringUtils.isEmpty(address)) { + binding.pumpBleConfigCurrentlySelectedPumpName.text = bleSelector.getText(PumpBLESelectorText.NO_SELECTED_PUMP) + binding.pumpBleConfigCurrentlySelectedPumpAddress.visibility = View.GONE + binding.pumpBleConfigButtonRemove.visibility = View.GONE + } else { + binding.pumpBleConfigCurrentlySelectedPumpAddress.visibility = View.VISIBLE + binding.pumpBleConfigButtonRemove.visibility = View.VISIBLE + binding.pumpBleConfigCurrentlySelectedPumpName.text = bleSelector.currentlySelectedPumpName() + binding.pumpBleConfigCurrentlySelectedPumpAddress.text = address + } + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean = + when (item.itemId) { + android.R.id.home -> { + finish() + true + } + + else -> false + } + + override fun onResume() { + super.onResume() + bleSelector.onResume() + prepareForScanning() + updateCurrentlySelectedBTDevice() + } + + override fun onDestroy() { + super.onDestroy() + if (scanning) { + stopLeDeviceScan(false) + } + bleSelector.onDestroy() + } + + private fun prepareForScanning() { + bleScanner = bluetoothAdapter!!.bluetoothLeScanner + settings = bleSelector.getScanSettings() + filters = bleSelector.getScanFilters() + } + + private val bleScanCallback: ScanCallback = object : ScanCallback() { + + override fun onScanResult(callbackType: Int, scanRecord: ScanResult) { + aapsLogger.debug(TAG, scanRecord.toString()) + runOnUiThread { if (addDevice(scanRecord)) deviceListAdapter.notifyDataSetChanged() } + } + + override fun onBatchScanResults(results: List) { + runOnUiThread { + var added = false + for (result in results) { + aapsLogger.debug(TAG, "SCAN: " + result.advertisingSid + " name=" + result.device.address) + if (addDevice(result)) added = true + } + if (added) + deviceListAdapter.notifyDataSetChanged() + } + } + + private fun addDevice(result: ScanResult): Boolean { + var device = result.device + + device = bleSelector.filterDevice(device) + + if (device == null) { + return false + } + + deviceListAdapter.addDevice(result) + if (!devicesMap.containsKey(device.address)) { + devicesMap[device.address] = device + } + return true + } + + override fun onScanFailed(errorCode: Int) { + aapsLogger.error(TAG, "Scan Failed - Error Code: $errorCode") + bleSelector.onScanFailed(this@PumpBLEConfigActivity, errorCode) + } + } + + private fun startLeDeviceScan() { + if (bleScanner == null) { + aapsLogger.error(LTag.PUMPBTCOMM, "startLeDeviceScan failed: bleScanner is null") + return + } + deviceListAdapter.clear() + deviceListAdapter.notifyDataSetChanged() + handler.postDelayed(stopScanAfterTimeoutRunnable, SCAN_PERIOD_MILLIS) + runOnUiThread { + binding.pumpBleConfigScanStart.isEnabled = false + binding.pumpBleConfigButtonScanStop.visibility = View.VISIBLE + } + scanning = true + bleScanner!!.startScan(filters, settings, bleScanCallback) + aapsLogger.debug(LTag.PUMPBTCOMM, "startLeDeviceScan: Scanning Start") + bleSelector.onStartLeDeviceScan(this@PumpBLEConfigActivity) + } + + private fun stopLeDeviceScan(manualStop: Boolean) { + if (scanning) { + scanning = false + bleScanner!!.stopScan(bleScanCallback) + aapsLogger.debug(LTag.PUMPBTCOMM, "stopLeDeviceScan: Scanning Stop") + bleSelector.onStopLeDeviceScan(this@PumpBLEConfigActivity) + handler.removeCallbacks(stopScanAfterTimeoutRunnable) + } + if (manualStop) { + bleSelector.onManualStopLeDeviceScan(this@PumpBLEConfigActivity) + } else { + bleSelector.onNonManualStopLeDeviceScan(this@PumpBLEConfigActivity) + } + + runOnUiThread { + binding.pumpBleConfigScanStart.isEnabled = true + binding.pumpBleConfigButtonScanStop.visibility = View.GONE + } + } + + private inner class LeDeviceListAdapter : BaseAdapter() { + + private var devicesList: ArrayList = arrayListOf() + private var devicesMap: MutableMap = mutableMapOf() + + fun addDevice(result: ScanResult) { + if (!devicesList.contains(result.device)) { + devicesList.add(result.device) + } + devicesMap[result.device] = result.rssi + notifyDataSetChanged() + } + + fun clear() { + devicesList.clear() + devicesMap.clear() + notifyDataSetChanged() + } + + override fun getCount(): Int { + val c = devicesList.size + aapsLogger.info(TAG, "D: count=$c") + return c + } + + override fun getItem(i: Int): Any = devicesList[i] + override fun getItemId(i: Int): Long = i.toLong() + + override fun getView(i: Int, convertView: View?, viewGroup: ViewGroup?): View { + var v = convertView + val holder: ViewHolder + if (v == null) { + v = View.inflate(applicationContext, R.layout.pump_ble_config_scan_item, null) + holder = ViewHolder() + holder.deviceAddress = v.findViewById(R.id.pump_ble_config_scan_item_device_address) + holder.deviceName = v.findViewById(R.id.pump_ble_config_scan_item_device_name) + v.tag = holder + } else { + // reuse view if already exists + holder = v.tag as ViewHolder + } + + val device = devicesList[i] + var deviceName = device.name + if (StringUtils.isBlank(deviceName)) { + deviceName = bleSelector.getUnknownPumpName() + } + deviceName += " [" + devicesMap[device] + "]" + val currentlySelectedAddress = bleSelector.currentlySelectedPumpAddress() // TODO + if (currentlySelectedAddress == device.address) { + deviceName += " (" + resources.getString(R.string.ble_config_scan_selected) + ")" + } + holder.deviceName!!.text = deviceName + holder.deviceAddress!!.text = device.address + return v!! + } + } + + internal class ViewHolder { + var deviceName: TextView? = null + var deviceAddress: TextView? = null + } + + companion object { + private val TAG = LTag.PUMPBTCOMM + private const val SCAN_PERIOD_MILLIS: Long = 15000 + } +} \ No newline at end of file diff --git a/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ui/PumpHistoryActivity.kt b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ui/PumpHistoryActivity.kt new file mode 100755 index 0000000000..a29cf41094 --- /dev/null +++ b/pump-common/src/main/java/info/nightscout/androidaps/plugins/pump/common/ui/PumpHistoryActivity.kt @@ -0,0 +1,217 @@ +package info.nightscout.androidaps.plugins.pump.common.ui + +import android.content.Context +import android.os.Bundle +import android.os.SystemClock +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.AdapterView +import android.widget.ArrayAdapter +import android.widget.TextView +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import dagger.android.support.DaggerAppCompatActivity +import info.nightscout.androidaps.interfaces.ActivePlugin +import info.nightscout.androidaps.plugins.pump.common.R +import info.nightscout.androidaps.plugins.pump.common.databinding.PumpHistoryActivityBinding +import info.nightscout.androidaps.plugins.pump.common.defs.PumpHistoryEntryGroup +import info.nightscout.androidaps.plugins.pump.common.driver.PumpDriverConfigurationCapable +import info.nightscout.androidaps.plugins.pump.common.driver.history.PumpHistoryDataProvider +import info.nightscout.androidaps.plugins.pump.common.driver.history.PumpHistoryEntry +import info.nightscout.androidaps.plugins.pump.common.driver.history.PumpHistoryText +import info.nightscout.androidaps.interfaces.ResourceHelper +import info.nightscout.shared.logging.AAPSLogger +import info.nightscout.shared.logging.LTag +import javax.inject.Inject + +class PumpHistoryActivity : DaggerAppCompatActivity() { + + @Inject lateinit var resourceHelper: ResourceHelper + @Inject lateinit var aapsLogger: AAPSLogger + @Inject lateinit var activePlugin: ActivePlugin + @Inject lateinit var context: Context + + var filteredHistoryList: MutableList = mutableListOf() + var typeListFull: List? = null + var fullList: MutableList = mutableListOf() + + private lateinit var historyDataProvider: PumpHistoryDataProvider + private lateinit var binding: PumpHistoryActivityBinding + + var manualChange = false + + lateinit var recyclerViewAdapter: RecyclerViewAdapter + + private fun prepareData() { + + val allData = historyDataProvider.getInitialData() + + aapsLogger.info(LTag.PUMP, "Loaded ${allData.size} items from database. [initialSize=${historyDataProvider.getInitialPeriod()}]") + + this.fullList.addAll(allData) + } + + private fun filterHistory(group: PumpHistoryEntryGroup) { + filteredHistoryList.clear() + + if (group === PumpHistoryEntryGroup.All) { + filteredHistoryList.addAll(fullList) + } else { + for (pumpHistoryEntry in fullList) { + if (historyDataProvider.isItemInSelection(pumpHistoryEntry.getEntryTypeGroup(), group)) { + filteredHistoryList.add(pumpHistoryEntry) + } + } + } + + aapsLogger.info(LTag.PUMP, "Filtered list ${filteredHistoryList.size} items (group ${group}), from full list (${fullList.size}).") + + recyclerViewAdapter.setHistoryListInternal(filteredHistoryList) + recyclerViewAdapter.notifyDataSetChanged() + + } + + override fun onResume() { + super.onResume() + //filterHistory(selectedGroup) + //setHistoryTypeSpinner() + //aapsLogger.info(LTag.PUMP, "onResume") + //binding.pumpHistoryRoot.requestLayout() + } + + private fun setHistoryTypeSpinner() { + manualChange = true + for (i in typeListFull!!.indices) { + if (typeListFull!![i].entryGroup === selectedGroup) { + binding.pumpHistoryType.setSelection(i) + break + } + } + SystemClock.sleep(200) + manualChange = false + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = PumpHistoryActivityBinding.inflate(layoutInflater) + setContentView(binding.root) + + // Configuration + val activePump = activePlugin.activePump + + if (activePump is PumpDriverConfigurationCapable) { + historyDataProvider = activePump.getPumpDriverConfiguration().getPumpHistoryDataProvider() + } else { + throw RuntimeException("PumpHistoryActivity can be used only with PumpDriverConfigurationCapable pump driver.") + } + + prepareData() + + binding.pumpHistoryRecyclerView.setHasFixedSize(true) + binding.pumpHistoryRecyclerView.layoutManager = LinearLayoutManager(this) + recyclerViewAdapter = RecyclerViewAdapter(filteredHistoryList) + binding.pumpHistoryRecyclerView.adapter = recyclerViewAdapter + binding.pumpHistoryStatus.visibility = View.GONE + typeListFull = getTypeList(historyDataProvider.getAllowedPumpHistoryGroups()) + val spinnerAdapter = ArrayAdapter(this, R.layout.spinner_centered, typeListFull!!) + + binding.pumpHistoryText.text = historyDataProvider.getText(PumpHistoryText.PUMP_HISTORY) + + binding.pumpHistoryType.adapter = spinnerAdapter + binding.pumpHistoryType.getLayoutParams().width = fromDpToSize(historyDataProvider.getSpinnerWidthInPixels()) + binding.pumpHistoryType.requestLayout(); + binding.pumpHistoryType.setOnItemSelectedListener(object : AdapterView.OnItemSelectedListener { + override fun onItemSelected(parent: AdapterView<*>?, view: View, position: Int, id: Long) { + if (manualChange) return + val selected = binding.pumpHistoryType.getSelectedItem() as TypeList + showingType = selected + selectedGroup = selected.entryGroup + filterHistory(selectedGroup) + val selectedText = parent!!.getChildAt(0) as TextView + selectedText.textSize = 15.0f // FIXME hack for selected item, also concerns pump_type marginTop + + binding.pumpHistoryTop.requestLayout() + } + + override fun onNothingSelected(parent: AdapterView<*>?) { + if (manualChange) return + filterHistory(PumpHistoryEntryGroup.All) + } + }) + binding.pumpHistoryTypeText.requestLayout() + } + + private fun getTypeList(list: List?): List { + val typeList = ArrayList() + for (pumpHistoryEntryGroup in list!!) { + typeList.add(TypeList(pumpHistoryEntryGroup)) + } + return typeList + } + + fun fromDpToSize(dpSize: Int): Int { + val scale = context.resources.displayMetrics.density + val pixelsFl = ((dpSize * scale) + 0.5f) + return pixelsFl.toInt() + } + + class TypeList internal constructor(var entryGroup: PumpHistoryEntryGroup) { + + var name: String + override fun toString(): String { + return name + } + + init { + name = entryGroup.translated!! + } + } + + class RecyclerViewAdapter internal constructor( + var historyList: List + ) : RecyclerView.Adapter() { + + fun setHistoryListInternal(historyList: List) { + this.historyList = historyList + } + + override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): HistoryViewHolder { + val v = LayoutInflater.from(viewGroup.context).inflate( + R.layout.pump_history_item, // + viewGroup, false + ) + return HistoryViewHolder(v) + } + + override fun onBindViewHolder(holder: HistoryViewHolder, position: Int) { + val record = historyList[position] + holder.timeView.text = record.getEntryDateTime() + holder.typeView.text = record.getEntryType() + holder.valueView.text = record.getEntryValue() + } + + override fun getItemCount(): Int { + return historyList.size + } + + class HistoryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { + + var timeView: TextView + var typeView: TextView + var valueView: TextView + + init { + timeView = itemView.findViewById(R.id.pump_history_time) + typeView = itemView.findViewById(R.id.pump_history_source) + valueView = itemView.findViewById(R.id.pump_history_description) + } + } + + } + + companion object { + var showingType: TypeList? = null + var selectedGroup = PumpHistoryEntryGroup.All + } +} \ No newline at end of file diff --git a/pump-common/src/main/res/layout/pump_ble_config_activity.xml b/pump-common/src/main/res/layout/pump_ble_config_activity.xml new file mode 100755 index 0000000000..b72fbd7e3f --- /dev/null +++ b/pump-common/src/main/res/layout/pump_ble_config_activity.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + +