diff --git a/.circleci/config.yml b/.circleci/config.yml index ea708e8e64..795c6415f1 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -68,6 +68,6 @@ workflows: # Inside the workflow, you provide the jobs you want to run, e.g this workflow runs the build-and-test job above. # CircleCI will run this workflow on every commit. # For more details on extending your workflow, see the configuration docs: https://circleci.com/docs/2.0/configuration-reference/#workflows - sample: + dotests: jobs: - build-and-test \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 5118670c6c..e9bcae3e17 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,6 +1,7 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-kapt' +apply plugin: 'kotlin-allopen' apply plugin: 'com.google.gms.google-services' apply plugin: 'com.hiya.jacoco-android' apply plugin: 'com.google.firebase.crashlytics' @@ -13,6 +14,11 @@ repositories { google() } +allOpen { + // allows mocking for classes w/o directly opening them for release builds + annotation 'info.nightscout.androidaps.annotations.OpenForTesting' +} + def generateGitBuild = { -> StringBuilder stringBuilder = new StringBuilder() try { @@ -185,6 +191,7 @@ dependencies { implementation project(':omnipod-eros') implementation project(':omnipod-dash') implementation project(':diaconn') + implementation project(':openhumans') implementation fileTree(include: ['*.jar'], dir: 'libs') diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ab34d9dfe1..f5aa72364e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -243,20 +243,6 @@ - - - - - - - - - - - diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.kt b/app/src/main/java/info/nightscout/androidaps/MainActivity.kt index 42559a543b..8a685a8703 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.kt @@ -95,7 +95,6 @@ class MainActivity : NoSplashAppCompatActivity() { private lateinit var binding: ActivityMainBinding - @kotlin.ExperimentalStdlibApi override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) Iconify.with(FontAwesomeModule()) @@ -361,7 +360,6 @@ class MainActivity : NoSplashAppCompatActivity() { // Correct place for calling setUserStats() would be probably MainApp // but we need to have it called at least once a day. Thus this location - @kotlin.ExperimentalStdlibApi private fun setUserStats() { if (!fabricPrivacy.fabricEnabled()) return val closedLoopEnabled = if (constraintChecker.isClosedLoopAllowed().value()) "CLOSED_LOOP_ENABLED" else "CLOSED_LOOP_DISABLED" diff --git a/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.kt b/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.kt index 6b0be2cc68..5ef938b134 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/HistoryBrowseActivity.kt @@ -93,11 +93,11 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() { overviewData = OverviewData(injector, aapsLogger, resourceHelper, dateUtil, sp, activePlugin, defaultValueHelper, profileFunction, config, loopPlugin, nsDeviceStatus, repository, overviewMenus, iobCobCalculator, translator) binding.left.setOnClickListener { - setTime(overviewData.fromTime - T.hours(rangeToDisplay.toLong()).msecs()) + adjustTimeRange(overviewData.fromTime - T.hours(rangeToDisplay.toLong()).msecs()) loadAll("onClickLeft") } binding.right.setOnClickListener { - setTime(overviewData.fromTime + T.hours(rangeToDisplay.toLong()).msecs()) + adjustTimeRange(overviewData.fromTime + T.hours(rangeToDisplay.toLong()).msecs()) loadAll("onClickRight") } binding.end.setOnClickListener { @@ -151,7 +151,11 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() { } val dm = DisplayMetrics() - windowManager?.defaultDisplay?.getMetrics(dm) + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) + display?.getRealMetrics(dm) + else + @Suppress("DEPRECATION") windowManager.defaultDisplay.getMetrics(dm) + axisWidth = if (dm.densityDpi <= 120) 3 else if (dm.densityDpi <= 160) 10 else if (dm.densityDpi <= 320) 35 else if (dm.densityDpi <= 420) 50 else if (dm.densityDpi <= 560) 70 else 80 binding.bgGraph.gridLabelRenderer?.gridColor = resourceHelper.gc(R.color.graphgrid) @@ -226,7 +230,6 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() { outState.putInt("rangeToDisplay", rangeToDisplay) outState.putLong("start", overviewData.fromTime) outState.putLong("end", overviewData.toTime) - } private fun prepareGraphsIfNeeded(numOfGraphs: Int) { @@ -266,6 +269,7 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() { @Suppress("SameParameterValue") private fun loadAll(from: String) { + updateDate() Thread { overviewData.prepareBasalData(from) overviewData.prepareTemporaryTargetData(from) @@ -277,18 +281,22 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() { } private fun setTime(start: Long) { - Calendar.getInstance().also { calendar -> + GregorianCalendar().also { calendar -> calendar.timeInMillis = start calendar[Calendar.MILLISECOND] = 0 calendar[Calendar.SECOND] = 0 calendar[Calendar.MINUTE] = 0 - calendar[Calendar.HOUR_OF_DAY] = 0 - overviewData.fromTime = calendar.timeInMillis - overviewData.toTime = overviewData.fromTime + T.hours(rangeToDisplay.toLong()).msecs() - overviewData.endTime = overviewData.toTime + calendar[Calendar.HOUR_OF_DAY] -= (calendar[Calendar.HOUR_OF_DAY] % rangeToDisplay) + adjustTimeRange(calendar.timeInMillis) } } + private fun adjustTimeRange(start: Long) { + overviewData.fromTime = start + overviewData.toTime = overviewData.fromTime + T.hours(rangeToDisplay.toLong()).msecs() + overviewData.endTime = overviewData.toTime + } + private fun runCalculation(from: String) { Thread { iobCobCalculator.stopCalculation(from) @@ -308,13 +316,17 @@ class HistoryBrowseActivity : NoSplashAppCompatActivity() { runningRefresh = false } + fun updateDate() { + binding.date.text = dateUtil.dateAndTimeString(overviewData.fromTime) + binding.zoom.text = rangeToDisplay.toString() + } + @Suppress("UNUSED_PARAMETER") @SuppressLint("SetTextI18n") fun updateGUI(from: String) { aapsLogger.debug(LTag.UI, "updateGui $from") - binding.date.text = dateUtil.dateAndTimeString(overviewData.fromTime) - binding.zoom.text = rangeToDisplay.toString() + updateDate() val pump = activePlugin.activePump val graphData = GraphData(injector, binding.bgGraph, overviewData) diff --git a/app/src/main/java/info/nightscout/androidaps/activities/MyPreferenceFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/MyPreferenceFragment.kt index 4c253c55f8..eb74f7b8cf 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/MyPreferenceFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/MyPreferenceFragment.kt @@ -20,6 +20,7 @@ import info.nightscout.androidaps.events.EventPreferenceChange import info.nightscout.androidaps.events.EventRebuildTabs import info.nightscout.androidaps.interfaces.PluginBase import info.nightscout.androidaps.interfaces.ProfileFunction +import info.nightscout.androidaps.plugin.general.openhumans.OpenHumansUploader import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin @@ -30,7 +31,6 @@ import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin import info.nightscout.androidaps.plugins.general.maintenance.MaintenancePlugin import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus -import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin import info.nightscout.androidaps.plugins.general.wear.WearPlugin diff --git a/app/src/main/java/info/nightscout/androidaps/activities/RequestDexcomPermissionActivity.kt b/app/src/main/java/info/nightscout/androidaps/activities/RequestDexcomPermissionActivity.kt index c5b03dc0f5..fd01500652 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/RequestDexcomPermissionActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/RequestDexcomPermissionActivity.kt @@ -7,10 +7,8 @@ import javax.inject.Inject class RequestDexcomPermissionActivity : DialogAppCompatActivity() { @Inject lateinit var dexcomPlugin: DexcomPlugin - @kotlin.ExperimentalStdlibApi private val requestCode = "AndroidAPS <3".map { it.code }.sum() - @kotlin.ExperimentalStdlibApi override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) requestPermissions(arrayOf(DexcomPlugin.PERMISSION), requestCode) diff --git a/app/src/main/java/info/nightscout/androidaps/activities/StatsActivity.kt b/app/src/main/java/info/nightscout/androidaps/activities/StatsActivity.kt index 8edeccfebd..82912e3da3 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/StatsActivity.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/StatsActivity.kt @@ -1,5 +1,6 @@ package info.nightscout.androidaps.activities +import android.annotation.SuppressLint import android.os.Bundle import info.nightscout.androidaps.R import info.nightscout.androidaps.database.entities.UserEntry.Action @@ -21,14 +22,28 @@ class StatsActivity : NoSplashAppCompatActivity() { private lateinit var binding: ActivityStatsBinding + @SuppressLint("SetTextI18n") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityStatsBinding.inflate(layoutInflater) setContentView(binding.root) - binding.tdds.text = tddCalculator.stats() - binding.tir.text = tirCalculator.stats() - binding.activity.text = activityMonitor.stats() + binding.tdds.text = getString(R.string.tdd) + ": " + getString(R.string.calculation_in_progress) + binding.tir.text = getString(R.string.tir) + ": " + getString(R.string.calculation_in_progress) + binding.activity.text = getString(R.string.activitymonitor) + ": " + getString(R.string.calculation_in_progress) + + Thread { + val tdds = tddCalculator.stats() + runOnUiThread { binding.tdds.text = tdds } + }.start() + Thread { + val tir = tirCalculator.stats() + runOnUiThread { binding.tir.text = tir } + }.start() + Thread { + val activity = activityMonitor.stats() + runOnUiThread { binding.activity.text = activity } + }.start() binding.ok.setOnClickListener { finish() } binding.reset.setOnClickListener { diff --git a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTemporaryBasalsFragment.kt b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTemporaryBasalsFragment.kt index 590fef204f..c856386cb6 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTemporaryBasalsFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/activities/fragments/TreatmentsTemporaryBasalsFragment.kt @@ -190,7 +190,6 @@ class TreatmentsTemporaryBasalsFragment : DaggerFragment() { override fun getItemCount(): Int = tempBasalList.size - @Deprecated("remove remove functionality after finish") inner class TempBasalsViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val binding = TreatmentsTempbasalsItemBinding.bind(itemView) diff --git a/app/src/main/java/info/nightscout/androidaps/data/defaultProfile/DefaultProfile.kt b/app/src/main/java/info/nightscout/androidaps/data/defaultProfile/DefaultProfile.kt index fa8b2774be..88066767bd 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/defaultProfile/DefaultProfile.kt +++ b/app/src/main/java/info/nightscout/androidaps/data/defaultProfile/DefaultProfile.kt @@ -11,6 +11,7 @@ import org.json.JSONObject import java.util.* import javax.inject.Inject import javax.inject.Singleton +import kotlin.math.abs @Singleton class DefaultProfile @Inject constructor(val dateUtil: DateUtil) { @@ -120,12 +121,12 @@ class DefaultProfile @Inject constructor(val dateUtil: DateUtil) { val high = map.ceilingEntry(key) var res: Array? = null if (low != null && high != null) { - res = if (Math.abs(key - low.key) < Math.abs(key - high.key)) + res = if (abs(key - low.key) < abs(key - high.key)) low.value else high.value } else if (low != null || high != null) { - res = if (low != null) low.value else high.value + res = if (low != null) low.value else high!!.value } return res } diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/ActivitiesModule.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/ActivitiesModule.kt index 08e25f456f..eff546fb62 100644 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/ActivitiesModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/ActivitiesModule.kt @@ -6,7 +6,6 @@ import info.nightscout.androidaps.MainActivity import info.nightscout.androidaps.activities.* import info.nightscout.androidaps.activities.HistoryBrowseActivity import info.nightscout.androidaps.plugins.general.maintenance.activities.LogSettingActivity -import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansLoginActivity import info.nightscout.androidaps.plugins.general.overview.activities.QuickWizardListActivity import info.nightscout.androidaps.plugins.general.smsCommunicator.activities.SmsCommunicatorOtpActivity import info.nightscout.androidaps.setupwizard.SetupWizardActivity @@ -28,6 +27,5 @@ abstract class ActivitiesModule { @ContributesAndroidInjector abstract fun contributesStatsActivity(): StatsActivity @ContributesAndroidInjector abstract fun contributesSurveyActivity(): SurveyActivity @ContributesAndroidInjector abstract fun contributesDefaultProfileActivity(): ProfileHelperActivity - @ContributesAndroidInjector abstract fun contributesOpenHumansLoginActivity(): OpenHumansLoginActivity } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppComponent.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppComponent.kt index 1404dad118..ab29e1f838 100644 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppComponent.kt +++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/AppComponent.kt @@ -16,6 +16,7 @@ import info.nightscout.androidaps.di.CoreModule import info.nightscout.androidaps.diaconn.di.DiaconnG8Module import info.nightscout.androidaps.insight.di.InsightDatabaseModule import info.nightscout.androidaps.insight.di.InsightModule +import info.nightscout.androidaps.plugin.general.openhumans.dagger.OpenHumansModule import info.nightscout.androidaps.plugins.pump.common.di.PumpCommonModule import info.nightscout.androidaps.plugins.pump.common.di.RileyLinkModule import info.nightscout.androidaps.plugins.pump.medtronic.di.MedtronicModule @@ -59,8 +60,8 @@ import javax.inject.Singleton InsightModule::class, InsightDatabaseModule::class, WorkersModule::class, - OHUploaderModule::class, - DiaconnG8Module::class + DiaconnG8Module::class, + OpenHumansModule::class ] ) interface AppComponent : AndroidInjector { diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/FragmentsModule.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/FragmentsModule.kt index 84e4ef80fb..f758398d62 100644 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/FragmentsModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/FragmentsModule.kt @@ -20,8 +20,6 @@ import info.nightscout.androidaps.plugins.general.automation.dialogs.EditTrigger import info.nightscout.androidaps.plugins.general.food.FoodFragment import info.nightscout.androidaps.plugins.general.maintenance.MaintenanceFragment import info.nightscout.androidaps.plugins.general.nsclient.NSClientFragment -import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansFragment -import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansLoginActivity import info.nightscout.androidaps.plugins.general.overview.OverviewFragment import info.nightscout.androidaps.plugins.general.overview.dialogs.EditQuickWizardDialog import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorFragment @@ -70,8 +68,6 @@ abstract class FragmentsModule { @ContributesAndroidInjector abstract fun contributesVirtualPumpFragment(): VirtualPumpFragment - @ContributesAndroidInjector abstract fun contributesOpenHumansFragment(): OpenHumansFragment - @ContributesAndroidInjector abstract fun contributesCalibrationDialog(): CalibrationDialog @ContributesAndroidInjector abstract fun contributesCarbsDialog(): CarbsDialog @ContributesAndroidInjector abstract fun contributesCareDialog(): CareDialog @@ -95,7 +91,5 @@ abstract class FragmentsModule { @ContributesAndroidInjector abstract fun contributesWizardDialog(): WizardDialog @ContributesAndroidInjector abstract fun contributesWizardInfoDialog(): WizardInfoDialog - @ContributesAndroidInjector abstract fun contributesExchangeAuthTokenDialog(): OpenHumansLoginActivity.ExchangeAuthTokenDialog - @ContributesAndroidInjector abstract fun contributesPasswordCheck(): PasswordCheck } \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OHUploaderModule.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OHUploaderModule.kt deleted file mode 100644 index bbf0765f96..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/OHUploaderModule.kt +++ /dev/null @@ -1,12 +0,0 @@ -package info.nightscout.androidaps.dependencyInjection - -import dagger.Module -import dagger.android.ContributesAndroidInjector -import info.nightscout.androidaps.plugins.general.openhumans.OHUploadWorker - -@Module -@Suppress("unused") -abstract class OHUploaderModule { - - @ContributesAndroidInjector abstract fun contributesOHUploadWorkerInjector(): OHUploadWorker -} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/PluginsModule.kt b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/PluginsModule.kt index 64cbcf3ab3..f861de7b07 100644 --- a/app/src/main/java/info/nightscout/androidaps/dependencyInjection/PluginsModule.kt +++ b/app/src/main/java/info/nightscout/androidaps/dependencyInjection/PluginsModule.kt @@ -10,6 +10,7 @@ import info.nightscout.androidaps.danar.DanaRPlugin import info.nightscout.androidaps.danars.DanaRSPlugin import info.nightscout.androidaps.diaconn.DiaconnG8Plugin import info.nightscout.androidaps.interfaces.PluginBase +import info.nightscout.androidaps.plugin.general.openhumans.OpenHumansUploader import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin @@ -346,6 +347,12 @@ abstract class PluginsModule { // @IntKey(480) // abstract fun bindOpenHumansPlugin(plugin: OpenHumansUploader): PluginBase + @Binds + @NotNSClient + @IntoMap + @IntKey(480) + abstract fun bindsOpenHumansPlugin(plugin: OpenHumansUploader): PluginBase + @Binds @AllConfigs @IntoMap diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/LoopDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/LoopDialog.kt index 493656f1cf..374ce2a36e 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/LoopDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/LoopDialog.kt @@ -3,6 +3,7 @@ package info.nightscout.androidaps.dialogs import android.content.Context import android.os.Bundle import android.os.Handler +import android.os.Looper import android.view.LayoutInflater import android.view.View import android.view.ViewGroup @@ -62,8 +63,8 @@ class LoopDialog : DaggerDialogFragment() { private var showOkCancel: Boolean = true private var _binding: DialogLoopBinding? = null - private var loopHandler = Handler() - private var refreshDialog: Runnable? = null + private var loopHandler = Handler(Looper.getMainLooper()) + private lateinit var refreshDialog: Runnable // This property is only valid between onCreateView and // onDestroyView. @@ -73,7 +74,10 @@ class LoopDialog : DaggerDialogFragment() { override fun onStart() { super.onStart() - dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) + dialog?.window?.setLayout( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ) } override fun onSaveInstanceState(savedInstanceState: Bundle) { @@ -158,7 +162,7 @@ class LoopDialog : DaggerDialogFragment() { val lgsEnabled = constraintChecker.isLgsAllowed(Constraint(true)) val apsMode = sp.getString(R.string.key_aps_mode, "open") if (profileFunction.isProfileValid("LoopDialogUpdateGUI")) { - if (loopPlugin.isEnabled(PluginType.LOOP)) { + if (loopPlugin.isEnabled()) { when { closedLoopAllowed.value() -> { binding.overviewCloseloop.visibility = (apsMode != "closed").toVisibility() @@ -166,6 +170,12 @@ class LoopDialog : DaggerDialogFragment() { binding.overviewOpenloop.visibility = (apsMode != "open").toVisibility() } + apsMode == "open" -> { + binding.overviewCloseloop.visibility = View.VISIBLE + binding.overviewLgsloop.visibility = View.GONE + binding.overviewOpenloop.visibility = View.GONE + } + lgsEnabled.value() -> { binding.overviewCloseloop.visibility = View.GONE binding.overviewLgsloop.visibility = (apsMode != "lgs").toVisibility() @@ -198,19 +208,21 @@ class LoopDialog : DaggerDialogFragment() { binding.overviewEnable.visibility = View.VISIBLE binding.overviewDisable.visibility = View.GONE binding.overviewSuspend.visibility = View.GONE + if (!loopPlugin.isDisconnected) { + binding.overviewPumpHeader.text = resourceHelper.gs(R.string.disconnectpump) + binding.overviewDisconnect15m.visibility = + pumpDescription.tempDurationStep15mAllowed.toVisibility() + binding.overviewDisconnect30m.visibility = + pumpDescription.tempDurationStep30mAllowed.toVisibility() + binding.overviewDisconnectButtons.visibility = View.VISIBLE + binding.overviewReconnect.visibility = View.GONE + } else { + binding.overviewPumpHeader.text = resourceHelper.gs(R.string.reconnect) + binding.overviewDisconnectButtons.visibility = View.GONE + binding.overviewReconnect.visibility = View.VISIBLE + } + binding.overviewLoop.visibility = (!loopPlugin.isSuspended && !loopPlugin.isDisconnected).toVisibility() } - if (!loopPlugin.isDisconnected) { - binding.overviewPumpHeader.text = resourceHelper.gs(R.string.disconnectpump) - binding.overviewDisconnect15m.visibility = pumpDescription.tempDurationStep15mAllowed.toVisibility() - binding.overviewDisconnect30m.visibility = pumpDescription.tempDurationStep30mAllowed.toVisibility() - binding.overviewDisconnectButtons.visibility = View.VISIBLE - binding.overviewReconnect.visibility = View.GONE - } else { - binding.overviewPumpHeader.text = resourceHelper.gs(R.string.reconnect) - binding.overviewDisconnectButtons.visibility = View.GONE - binding.overviewReconnect.visibility = View.VISIBLE - } - binding.overviewLoop.visibility = (!loopPlugin.isSuspended && !loopPlugin.isDisconnected).toVisibility() } val profile = profileFunction.getProfile() val profileStore = activePlugin.activeProfileSource.profile @@ -415,7 +427,7 @@ class LoopDialog : DaggerDialogFragment() { it.commitAllowingStateLoss() } } catch (e: IllegalStateException) { - aapsLogger.debug(e.localizedMessage) + aapsLogger.debug(e.localizedMessage ?: e.toString()) } } } diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt index 9d65cc01e1..1483359162 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt @@ -384,7 +384,7 @@ class WizardDialog : DaggerDialogFragment() { it.commitAllowingStateLoss() } } catch (e: IllegalStateException) { - aapsLogger.debug(e.localizedMessage) + aapsLogger.debug(e.localizedMessage ?: "") } } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.kt index 82a7713b5d..c6955fcd34 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/loop/LoopPlugin.kt @@ -12,6 +12,7 @@ import androidx.core.app.NotificationCompat import dagger.android.HasAndroidInjector import info.nightscout.androidaps.* import info.nightscout.androidaps.activities.ErrorHelperActivity +import info.nightscout.androidaps.annotations.OpenForTesting import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.data.PumpEnactResult @@ -65,8 +66,9 @@ import javax.inject.Inject import javax.inject.Singleton import kotlin.math.abs +@OpenForTesting @Singleton -open class LoopPlugin @Inject constructor( +class LoopPlugin @Inject constructor( injector: HasAndroidInjector, aapsLogger: AAPSLogger, private val aapsSchedulers: AapsSchedulers, diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/DetermineBasalAdapterAMAJS.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/DetermineBasalAdapterAMAJS.kt index adb15e8b29..5eb53e3e46 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/DetermineBasalAdapterAMAJS.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/DetermineBasalAdapterAMAJS.kt @@ -17,7 +17,6 @@ import info.nightscout.androidaps.plugins.aps.logger.LoggerCallback import info.nightscout.androidaps.plugins.aps.loop.ScriptReader import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker -import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus import info.nightscout.androidaps.utils.sharedPreferences.SP import org.json.JSONArray @@ -40,7 +39,6 @@ class DetermineBasalAdapterAMAJS internal constructor(scriptReader: ScriptReader @Inject lateinit var sp: SP @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var iobCobCalculator: IobCobCalculator - @Inject lateinit var openHumansUploader: OpenHumansUploader private val mScriptReader: ScriptReader private var profile = JSONObject() @@ -116,7 +114,6 @@ class DetermineBasalAdapterAMAJS internal constructor(scriptReader: ScriptReader aapsLogger.debug(LTag.APS, "Result: $result") try { val resultJson = JSONObject(result) - openHumansUploader.enqueueAMAData(profile, glucoseStatus, iobData, mealData, currentTemp, autosensData, resultJson) determineBasalResultAMA = DetermineBasalResultAMA(injector, jsResult, resultJson) } catch (e: JSONException) { aapsLogger.error(LTag.APS, "Unhandled exception", e) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAFragment.kt index 1c4de77907..acbbf1191b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAFragment.kt @@ -58,7 +58,6 @@ class OpenAPSAMAFragment : DaggerFragment() { } @Synchronized - @kotlin.ExperimentalStdlibApi override fun onResume() { super.onResume() @@ -91,7 +90,6 @@ class OpenAPSAMAFragment : DaggerFragment() { } @Synchronized - @kotlin.ExperimentalStdlibApi private fun updateGUI() { if (_binding == null) return openAPSAMAPlugin.lastAPSResult?.let { lastAPSResult -> diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.kt index 2c34f41a06..f697f23e20 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.kt @@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.aps.openAPSAMA import android.content.Context import dagger.android.HasAndroidInjector import info.nightscout.androidaps.R +import info.nightscout.androidaps.annotations.OpenForTesting import info.nightscout.androidaps.interfaces.Profile import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.ValueWrapper @@ -27,8 +28,9 @@ import org.json.JSONException import javax.inject.Inject import javax.inject.Singleton +@OpenForTesting @Singleton -open class OpenAPSAMAPlugin @Inject constructor( +class OpenAPSAMAPlugin @Inject constructor( injector: HasAndroidInjector, aapsLogger: AAPSLogger, private val rxBus: RxBusWrapper, diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalAdapterSMBJS.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalAdapterSMBJS.kt index b32682c102..bdb1039bd2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalAdapterSMBJS.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalAdapterSMBJS.kt @@ -17,7 +17,6 @@ import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.plugins.aps.logger.LoggerCallback import info.nightscout.androidaps.plugins.aps.loop.ScriptReader import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker -import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus import info.nightscout.androidaps.utils.SafeParse import info.nightscout.androidaps.utils.resources.ResourceHelper @@ -41,7 +40,6 @@ class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader: @Inject lateinit var profileFunction: ProfileFunction @Inject lateinit var iobCobCalculator: IobCobCalculator @Inject lateinit var activePlugin: ActivePlugin - @Inject lateinit var openHumansUploader: OpenHumansUploader private var profile = JSONObject() private var mGlucoseStatus = JSONObject() @@ -129,7 +127,6 @@ class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader: aapsLogger.debug(LTag.APS, "Result: $result") try { val resultJson = JSONObject(result) - openHumansUploader.enqueueSMBData(profile, mGlucoseStatus, iobData, mealData, currentTemp, autosensData, microBolusAllowed, smbAlwaysAllowed, resultJson) determineBasalResultSMB = DetermineBasalResultSMB(injector, resultJson) } catch (e: JSONException) { aapsLogger.error(LTag.APS, "Unhandled exception", e) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBFragment.kt index f5e03f602f..61e52b0821 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBFragment.kt @@ -59,7 +59,6 @@ class OpenAPSSMBFragment : DaggerFragment() { } @Synchronized - @kotlin.ExperimentalStdlibApi override fun onResume() { super.onResume() disposable += rxBus @@ -91,7 +90,6 @@ class OpenAPSSMBFragment : DaggerFragment() { } @Synchronized - @kotlin.ExperimentalStdlibApi fun updateGUI() { if (_binding == null) return openAPSSMBPlugin.lastAPSResult?.let { lastAPSResult -> diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.kt index fb5d265335..3b65f213f7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.kt @@ -5,6 +5,7 @@ import androidx.preference.PreferenceFragmentCompat import androidx.preference.SwitchPreference import dagger.android.HasAndroidInjector import info.nightscout.androidaps.R +import info.nightscout.androidaps.annotations.OpenForTesting import info.nightscout.androidaps.database.AppRepository import info.nightscout.androidaps.database.ValueWrapper import info.nightscout.androidaps.extensions.target @@ -27,8 +28,9 @@ import info.nightscout.androidaps.utils.sharedPreferences.SP import javax.inject.Inject import javax.inject.Singleton +@OpenForTesting @Singleton -open class OpenAPSSMBPlugin @Inject constructor( +class OpenAPSSMBPlugin @Inject constructor( injector: HasAndroidInjector, aapsLogger: AAPSLogger, private val rxBus: RxBusWrapper, diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ConfigBuilderFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ConfigBuilderFragment.kt index 74bbac3d1d..862a8c918a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ConfigBuilderFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ConfigBuilderFragment.kt @@ -141,6 +141,7 @@ class ConfigBuilderFragment : DaggerFragment() { private val enabledExclusive: RadioButton = baseView.findViewById(R.id.plugin_enabled_exclusive) private val enabledInclusive: CheckBox = baseView.findViewById(R.id.plugin_enabled_inclusive) private val pluginIcon: ImageView = baseView.findViewById(R.id.plugin_icon) + private val pluginIcon2: ImageView = baseView.findViewById(R.id.plugin_icon2) private val pluginName: TextView = baseView.findViewById(R.id.plugin_name) private val pluginDescription: TextView = baseView.findViewById(R.id.plugin_description) private val pluginPreferences: ImageButton = baseView.findViewById(R.id.plugin_preferences) @@ -184,6 +185,12 @@ class ConfigBuilderFragment : DaggerFragment() { if (plugin.menuIcon != -1) { pluginIcon.visibility = View.VISIBLE pluginIcon.setImageDrawable(context?.let { ContextCompat.getDrawable(it, plugin.menuIcon) }) + if (plugin.menuIcon2 != -1) { + pluginIcon2.visibility = View.VISIBLE + pluginIcon2.setImageDrawable(context?.let { ContextCompat.getDrawable(it, plugin.menuIcon2) }) + } else { + pluginIcon2.visibility = View.GONE + } } else { pluginIcon.visibility = View.GONE } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/ObjectivesPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/ObjectivesPlugin.kt index 3368f86919..670d164503 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/ObjectivesPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/ObjectivesPlugin.kt @@ -100,7 +100,6 @@ class ObjectivesPlugin @Inject constructor( sp.putBoolean(R.string.key_objectiveusescale, false) } - @kotlin.ExperimentalStdlibApi fun completeObjectives(activity: FragmentActivity, request: String) { val requestCode = sp.getString(R.string.key_objectives_request_code, "") var url = sp.getString(R.string.key_nsclientinternal_url, "").lowercase(Locale.getDefault()) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/objectives/Objective3.kt b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/objectives/Objective3.kt index 5247e18fac..2ccd96f3b3 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/objectives/Objective3.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/objectives/objectives/Objective3.kt @@ -29,7 +29,6 @@ class Objective3 @Inject constructor(injector: HasAndroidInjector) : Objective(i override fun specialActionEnabled(): Boolean = nsClientPlugin.nsClientService?.isConnected == true && nsClientPlugin.nsClientService?.hasWriteAuth == true - @kotlin.ExperimentalStdlibApi override fun specialAction(activity: FragmentActivity, input: String) { objectivesPlugin.completeObjectives(activity, input) } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/signatureVerifier/SignatureVerifierPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/signatureVerifier/SignatureVerifierPlugin.kt index 7c41902a08..d4a7a73dca 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/signatureVerifier/SignatureVerifierPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/signatureVerifier/SignatureVerifierPlugin.kt @@ -152,7 +152,6 @@ class SignatureVerifierPlugin @Inject constructor( return sb.toString() } - @kotlin.ExperimentalStdlibApi fun singleCharUnMap(shortHash: String): String { val array = ByteArray(shortHash.length) val sb = StringBuilder() diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/storage/StorageConstraintPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/storage/StorageConstraintPlugin.kt index cebf039967..e474c94906 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/constraints/storage/StorageConstraintPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/constraints/storage/StorageConstraintPlugin.kt @@ -5,6 +5,7 @@ import android.os.StatFs import dagger.android.HasAndroidInjector import info.nightscout.androidaps.Constants import info.nightscout.androidaps.R +import info.nightscout.androidaps.annotations.OpenForTesting import info.nightscout.androidaps.interfaces.Constraint import info.nightscout.androidaps.interfaces.Constraints import info.nightscout.androidaps.interfaces.PluginBase @@ -20,8 +21,9 @@ import info.nightscout.androidaps.utils.resources.ResourceHelper import javax.inject.Inject import javax.inject.Singleton +@OpenForTesting @Singleton -open class StorageConstraintPlugin @Inject constructor( +class StorageConstraintPlugin @Inject constructor( injector: HasAndroidInjector, aapsLogger: AAPSLogger, resourceHelper: ResourceHelper, diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt index 60fc700dcf..ada8f9eab0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/actions/ActionsFragment.kt @@ -115,7 +115,10 @@ class ActionsFragment : DaggerFragment() { savedInstanceState: Bundle?): View? { //check screen width dm = DisplayMetrics() - activity?.windowManager?.defaultDisplay?.getMetrics(dm) + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) + activity?.display?.getRealMetrics(dm) + else + @Suppress("DEPRECATION") activity?.windowManager?.defaultDisplay?.getMetrics(dm) val screenWidth = dm.widthPixels val screenHeight = dm.heightPixels diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/food/FoodFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/food/FoodFragment.kt index 364f64e180..97f780e842 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/food/FoodFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/food/FoodFragment.kt @@ -67,7 +67,6 @@ class FoodFragment : DaggerFragment() { return binding.root } - @kotlin.ExperimentalStdlibApi override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -129,7 +128,6 @@ class FoodFragment : DaggerFragment() { } @Synchronized - @kotlin.ExperimentalStdlibApi override fun onResume() { super.onResume() disposable.add(rxBus @@ -141,7 +139,6 @@ class FoodFragment : DaggerFragment() { swapAdapter() } - @kotlin.ExperimentalStdlibApi private fun swapAdapter() { disposable += repository .getFoodData() @@ -202,7 +199,6 @@ class FoodFragment : DaggerFragment() { } } - @kotlin.ExperimentalStdlibApi private fun filterData() { val textFilter = binding.filter.text.toString() val categoryFilter = binding.category.selectedItem?.toString() diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/MaintenancePlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/MaintenancePlugin.kt index deb2d9e7e8..73395d4e96 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/MaintenancePlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/maintenance/MaintenancePlugin.kt @@ -73,6 +73,7 @@ class MaintenancePlugin @Inject constructor( val files = logDir.listFiles { _: File?, name: String -> (name.startsWith("AndroidAPS") && name.endsWith(".zip")) } + if (files == null || files.isEmpty()) return Arrays.sort(files) { f1: File, f2: File -> f2.name.compareTo(f1.name) } var delFiles = listOf(*files) val amount = sp.getInt(R.string.key_logshipper_amount, keep) @@ -85,9 +86,8 @@ class MaintenancePlugin @Inject constructor( } val exportDir = fileListProvider.ensureTempDirExists() if (exportDir.exists()) { - val expFiles = exportDir.listFiles() - for (file in expFiles) { - file.delete() + exportDir.listFiles()?.let { expFiles -> + for (file in expFiles) file.delete() } exportDir.delete() } @@ -109,7 +109,7 @@ class MaintenancePlugin @Inject constructor( (name.startsWith("AndroidAPS") && (name.endsWith(".log") || name.endsWith(".zip") && !name.endsWith(loggerUtils.suffix))) - } + } ?: emptyArray() Arrays.sort(files) { f1: File, f2: File -> f2.name.compareTo(f1.name) } val result = listOf(*files) var toIndex = amount diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/DataSyncSelectorImplementation.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/DataSyncSelectorImplementation.kt index a164ab6ab9..d894b6c146 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/DataSyncSelectorImplementation.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/DataSyncSelectorImplementation.kt @@ -78,8 +78,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - private var lastBolusId = -1L - private var lastBolusTime = -1L + @Volatile private var lastBolusId = -1L + @Volatile private var lastBolusTime = -1L override fun processChangedBolusesCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastBolusIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L @@ -121,8 +121,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - private var lastCarbsId = -1L - private var lastCarbsTime = -1L + @Volatile private var lastCarbsId = -1L + @Volatile private var lastCarbsTime = -1L override fun processChangedCarbsCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastCarbsIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L @@ -164,8 +164,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - private var lastBcrId = -1L - private var lastBcrTime = -1L + @Volatile private var lastBcrId = -1L + @Volatile private var lastBcrTime = -1L override fun processChangedBolusCalculatorResultsCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastBolusCalculatorResultIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L @@ -207,8 +207,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - private var lastTtId = -1L - private var lastTtTime = -1L + @Volatile private var lastTtId = -1L + @Volatile private var lastTtTime = -1L override fun processChangedTempTargetsCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastTempTargetIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L @@ -250,8 +250,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - private var lastFoodId = -1L - private var lastFoodTime = -1L + @Volatile private var lastFoodId = -1L + @Volatile private var lastFoodTime = -1L override fun processChangedFoodsCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastFoodIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L @@ -293,8 +293,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - private var lastGvId = -1L - private var lastGvTime = -1L + @Volatile private var lastGvId = -1L + @Volatile private var lastGvTime = -1L override fun processChangedGlucoseValuesCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastGlucoseValueIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L @@ -342,8 +342,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - private var lastTeId = -1L - private var lastTeTime = -1L + @Volatile private var lastTeId = -1L + @Volatile private var lastTeTime = -1L override fun processChangedTherapyEventsCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastTherapyEventIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L @@ -384,8 +384,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - private var lastDsId = -1L - private var lastDsTime = -1L + @Volatile private var lastDsId = -1L + @Volatile private var lastDsTime = -1L override fun processChangedDeviceStatusesCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastDeviceStatusIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L @@ -426,8 +426,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - private var lastTbrId = -1L - private var lastTbrTime = -1L + @Volatile private var lastTbrId = -1L + @Volatile private var lastTbrTime = -1L override fun processChangedTemporaryBasalsCompat(): Boolean { val useAbsolute = sp.getBoolean(R.string.key_ns_sync_use_absolute, false) val lastDbIdWrapped = appRepository.getLastTemporaryBasalIdWrapped().blockingGet() @@ -477,8 +477,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - private var lastEbId = -1L - private var lastEbTime = -1L + @Volatile private var lastEbId = -1L + @Volatile private var lastEbTime = -1L override fun processChangedExtendedBolusesCompat(): Boolean { val useAbsolute = sp.getBoolean(R.string.key_ns_sync_use_absolute, false) val lastDbIdWrapped = appRepository.getLastExtendedBolusIdWrapped().blockingGet() @@ -527,8 +527,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - private var lastPsId = -1L - private var lastPsTime = -1L + @Volatile private var lastPsId = -1L + @Volatile private var lastPsTime = -1L override fun processChangedProfileSwitchesCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastProfileSwitchIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L @@ -570,8 +570,8 @@ class DataSyncSelectorImplementation @Inject constructor( } } - private var lastOeId = -1L - private var lastOeTime = -1L + @Volatile private var lastOeId = -1L + @Volatile private var lastOeTime = -1L override fun processChangedOfflineEventsCompat(): Boolean { val lastDbIdWrapped = appRepository.getLastOfflineEventIdWrapped().blockingGet() val lastDbId = if (lastDbIdWrapped is ValueWrapper.Existing) lastDbIdWrapped.value else 0L diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.kt index dd31516ac3..8d0a8691c1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/nsclient/services/NSClientService.kt @@ -112,7 +112,6 @@ class NSClientService : DaggerService() { var latestDateInReceivedData: Long = 0 @SuppressLint("WakelockTimeout") - @kotlin.ExperimentalStdlibApi override fun onCreate() { super.onCreate() wakeLock = (getSystemService(Context.POWER_SERVICE) as PowerManager).newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AndroidAPS:NSClientService") @@ -236,7 +235,6 @@ class NSClientService : DaggerService() { return START_STICKY } - @kotlin.ExperimentalStdlibApi fun initialize() { dataCounter = 0 readPreferences() @@ -651,7 +649,6 @@ class NSClientService : DaggerService() { } } - @kotlin.ExperimentalStdlibApi fun restart() { destroy() initialize() diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OHUploadWorker.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OHUploadWorker.kt deleted file mode 100644 index 16c9dddec6..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OHUploadWorker.kt +++ /dev/null @@ -1,70 +0,0 @@ -package info.nightscout.androidaps.plugins.general.openhumans - -import android.app.Notification -import android.content.Context -import android.net.wifi.WifiManager -import androidx.core.app.NotificationCompat -import androidx.work.ForegroundInfo -import androidx.work.RxWorker -import androidx.work.WorkerParameters -import info.nightscout.androidaps.MainApp -import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader.Companion.NOTIFICATION_CHANNEL -import info.nightscout.androidaps.plugins.general.openhumans.OpenHumansUploader.Companion.UPLOAD_NOTIFICATION_ID -import info.nightscout.androidaps.utils.resources.ResourceHelper -import info.nightscout.androidaps.utils.sharedPreferences.SP -import io.reactivex.Single -import java.util.concurrent.TimeUnit -import javax.inject.Inject - -class OHUploadWorker(context: Context, workerParameters: WorkerParameters) - : RxWorker(context, workerParameters) { - - @Inject - lateinit var sp: SP - - @Inject - lateinit var openHumansUploader: OpenHumansUploader - - @Inject - lateinit var resourceHelper: ResourceHelper - - @kotlin.ExperimentalStdlibApi - override fun createWork(): Single =Single.just(Result.success()) -/* - = Single.defer { - - // Here we inject every time we create work - // We could build our own WorkerFactory with dagger but this will create conflicts with other Workers - // (see https://medium.com/wonderquill/how-to-pass-custom-parameters-to-rxworker-worker-using-dagger-2-f4cfbc9892ba) - // This class will be replaced with new DB - - (applicationContext as MainApp).androidInjector().inject(this) - - val wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as? WifiManager - val wifiOnly = sp.getBoolean("key_oh_wifi_only", true) - val isConnectedToWifi = wifiManager?.isWifiEnabled ?: false && wifiManager?.connectionInfo?.networkId != -1 - if (!wifiOnly || (wifiOnly && isConnectedToWifi)) { - setForegroundAsync(createForegroundInfo()) - openHumansUploader.uploadDataSegmentally() - .andThen(Single.just(Result.success())) - .onErrorResumeNext { Single.just(Result.retry()) } - } else { - Single.just(Result.retry()) - } - } -*/ - private fun createForegroundInfo(): ForegroundInfo { - val title = resourceHelper.gs(info.nightscout.androidaps.R.string.open_humans) - - val notification: Notification = NotificationCompat.Builder(applicationContext, NOTIFICATION_CHANNEL) - .setContentTitle(title) - .setTicker(title) - .setContentText(resourceHelper.gs(info.nightscout.androidaps.R.string.your_phone_is_upload_data)) - .setSmallIcon(info.nightscout.androidaps.R.drawable.notif_icon) - .setOngoing(true) - .setProgress(0, 0 , true) - .build() - return ForegroundInfo(UPLOAD_NOTIFICATION_ID, notification) - } - -} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OpenHumansAPI.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OpenHumansAPI.kt deleted file mode 100644 index 91fa60ca25..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OpenHumansAPI.kt +++ /dev/null @@ -1,191 +0,0 @@ -package info.nightscout.androidaps.plugins.general.openhumans - -import android.annotation.SuppressLint -import android.util.Base64 -import io.reactivex.Completable -import io.reactivex.Single -import io.reactivex.disposables.Disposables -import okhttp3.* -import okio.BufferedSink -import org.json.JSONArray -import org.json.JSONObject -import java.io.IOException -import java.text.SimpleDateFormat -import java.util.* - -class OpenHumansAPI( - private val baseUrl: String, - clientId: String, - clientSecret: String, - private val redirectUri: String -) { - - private val authHeader = "Basic " + Base64.encodeToString("$clientId:$clientSecret".toByteArray(), Base64.NO_WRAP) - private val client = OkHttpClient() - - fun exchangeAuthToken(code: String): Single = sendTokenRequest(FormBody.Builder() - .add("grant_type", "authorization_code") - .add("redirect_uri", redirectUri) - .add("code", code) - .build()) - - fun refreshAccessToken(refreshToken: String): Single = sendTokenRequest(FormBody.Builder() - .add("grant_type", "refresh_token") - .add("redirect_uri", redirectUri) - .add("refresh_token", refreshToken) - .build()) - - private fun sendTokenRequest(body: FormBody) = Request.Builder() - .url("$baseUrl/oauth2/token/") - .addHeader("Authorization", authHeader) - .post(body) - .build() - .toSingle() - .map { response -> - response.use { _ -> - val responseBody = response.body - val jsonObject = responseBody?.let { JSONObject(it.string()) } - if (!response.isSuccessful) throw OHHttpException(response.code, response.message, jsonObject?.getString("error")) - if (jsonObject == null) throw OHHttpException(response.code, response.message, "No body") - if (!jsonObject.has("expires_in")) throw OHMissingFieldException("expires_in") - OAuthTokens( - accessToken = jsonObject.getString("access_token") - ?: throw OHMissingFieldException("access_token"), - refreshToken = jsonObject.getString("refresh_token") - ?: throw OHMissingFieldException("refresh_token"), - expiresAt = response.sentRequestAtMillis + jsonObject.getInt("expires_in") * 1000L - ) - } - } - - fun getProjectMemberId(accessToken: String): Single = Request.Builder() - .url("$baseUrl/api/direct-sharing/project/exchange-member/?access_token=$accessToken") - .get() - .build() - .toSingle() - .map { - it.jsonBody.getString("project_member_id") - ?: throw OHMissingFieldException("project_member_id") - } - - fun prepareFileUpload(accessToken: String, fileName: String, metadata: FileMetadata): Single = Request.Builder() - .url("$baseUrl/api/direct-sharing/project/files/upload/direct/?access_token=$accessToken") - .post(FormBody.Builder() - .add("filename", fileName) - .add("metadata", metadata.toJSON().toString()) - .build()) - .build() - .toSingle() - .map { - val json = it.jsonBody - PreparedUpload( - fileId = json.getString("id") ?: throw OHMissingFieldException("id"), - uploadURL = json.getString("url") ?: throw OHMissingFieldException("url") - ) - } - - fun uploadFile(url: String, content: ByteArray): Completable = Request.Builder() - .url(url) - .put(object : RequestBody() { - override fun contentType(): MediaType? = null - - override fun contentLength() = content.size.toLong() - - override fun writeTo(sink: BufferedSink) { - sink.write(content) - } - }) - .build() - .toSingle() - .doOnSuccess { response -> - response.use { _ -> - if (!response.isSuccessful) throw OHHttpException(response.code, response.message, null) - } - } - .ignoreElement() - - fun completeFileUpload(accessToken: String, fileId: String): Completable = Request.Builder() - .url("$baseUrl/api/direct-sharing/project/files/upload/complete/?access_token=$accessToken") - .post(FormBody.Builder() - .add("file_id", fileId) - .build()) - .build() - .toSingle() - .doOnSuccess { it.jsonBody } - .ignoreElement() - - private fun Request.toSingle() = Single.create { - val call = client.newCall(this) - call.enqueue(object : Callback { - override fun onFailure(call: Call, e: IOException) { - it.tryOnError(e) - } - - override fun onResponse(call: Call, response: Response) { - it.onSuccess(response) - } - }) - it.setDisposable(Disposables.fromRunnable { call.cancel() }) - } - - private val Response.jsonBody - get() = use { _ -> - val jsonObject = body?.let { JSONObject(it.string()) } - ?: throw OHHttpException(code, message, null) - if (!isSuccessful) throw OHHttpException(code, message, jsonObject.getString("detail")) - jsonObject - } - - data class OAuthTokens( - val accessToken: String, - val refreshToken: String, - val expiresAt: Long - ) - - data class FileMetadata( - val tags: List, - val description: String, - val md5: String? = null, - val creationDate: Long? = null, - val startDate: Long? = null, - val endDate: Long? = null - ) { - - fun toJSON(): JSONObject { - val jsonObject = JSONObject() - jsonObject.put("tags", JSONArray().apply { tags.forEach { put(it) } }) - jsonObject.put("description", description) - jsonObject.put("md5", md5) - creationDate?.let { jsonObject.put("creation_date", iso8601DateFormatter.format(Date(it))) } - startDate?.let { jsonObject.put("start_date", iso8601DateFormatter.format(Date(it))) } - endDate?.let { jsonObject.put("end_date", iso8601DateFormatter.format(Date(it))) } - return jsonObject - } - } - - data class PreparedUpload( - val fileId: String, - val uploadURL: String - ) - - data class OHHttpException( - val code: Int, - val meaning: String, - val detail: String? - ) : RuntimeException() { - - override val message: String get() = toString() - } - - data class OHMissingFieldException( - val name: String - ) : RuntimeException() { - - override val message: String get() = toString() - } - - companion object { - @SuppressLint("SimpleDateFormat") - private val iso8601DateFormatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX") - } -} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OpenHumansFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OpenHumansFragment.kt deleted file mode 100644 index 9178e8aca8..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OpenHumansFragment.kt +++ /dev/null @@ -1,114 +0,0 @@ -package info.nightscout.androidaps.plugins.general.openhumans - -import android.content.Intent -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import android.widget.Button -import android.widget.TextView -import androidx.work.WorkManager -import dagger.android.support.DaggerFragment -import info.nightscout.androidaps.R -import info.nightscout.androidaps.events.Event -import info.nightscout.androidaps.plugins.bus.RxBusWrapper -import info.nightscout.androidaps.utils.alertDialogs.OKDialog -import info.nightscout.androidaps.utils.resources.ResourceHelper -import info.nightscout.androidaps.utils.rx.AapsSchedulers -import io.reactivex.BackpressureStrategy -import io.reactivex.Single -import io.reactivex.disposables.CompositeDisposable -import io.reactivex.rxkotlin.plusAssign -import java.util.concurrent.TimeUnit -import javax.inject.Inject - -class OpenHumansFragment : DaggerFragment() { - - private var viewsCreated = false - private var login: Button? = null - private var logout: Button? = null - private var memberId: TextView? = null - private var queueSize: TextView? = null - private var workerState: TextView? = null - private var queueSizeValue = 0L - private val compositeDisposable = CompositeDisposable() - - @Inject lateinit var rxBus: RxBusWrapper - @Inject lateinit var openHumansUploader: OpenHumansUploader - @Inject lateinit var resourceHelper: ResourceHelper - @Inject lateinit var aapsSchedulers: AapsSchedulers - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - // compositeDisposable += Single.fromCallable { databaseHelper.getOHQueueSize() } - // .subscribeOn(aapsSchedulers.io) - // .repeatWhen { - // rxBus.toObservable(UpdateViewEvent::class.java) - // .cast(Any::class.java) - // .mergeWith(rxBus.toObservable(UpdateQueueEvent::class.java) - // .throttleLatest(5, TimeUnit.SECONDS)) - // .toFlowable(BackpressureStrategy.LATEST) - // } - // .observeOn(aapsSchedulers.main) - // .subscribe({ - // queueSizeValue = it - // updateGUI() - // }, {}) - context?.applicationContext?.let { appContext -> - WorkManager.getInstance(appContext).getWorkInfosForUniqueWorkLiveData(OpenHumansUploader.WORK_NAME).observe(this, { - val workInfo = it.lastOrNull() - if (workInfo == null) { - workerState?.visibility = View.GONE - } else { - workerState?.visibility = View.VISIBLE - workerState?.text = getString(R.string.worker_state, workInfo.state.toString()) - } - }) - } - } - - override fun onDestroy() { - compositeDisposable.clear() - super.onDestroy() - } - - override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { - val view = inflater.inflate(R.layout.fragment_open_humans, container, false) - login = view.findViewById(R.id.login) - logout = view.findViewById(R.id.logout) - memberId = view.findViewById(R.id.member_id) - queueSize = view.findViewById(R.id.queue_size) - workerState = view.findViewById(R.id.worker_state) - login!!.setOnClickListener { startActivity(Intent(context, OpenHumansLoginActivity::class.java)) } - logout!!.setOnClickListener { - activity?.let { activity -> OKDialog.showConfirmation(activity, resourceHelper.gs(R.string.oh_logout_confirmation)) { openHumansUploader.logout() } } - } - viewsCreated = true - updateGUI() - return view - } - - override fun onDestroyView() { - viewsCreated = false - login = null - logout = null - memberId = null - queueSize = null - super.onDestroyView() - } - - fun updateGUI() { - if (viewsCreated) { - queueSize!!.text = getString(R.string.queue_size, queueSizeValue) - val projectMemberId = openHumansUploader.projectMemberId - memberId!!.text = getString(R.string.project_member_id, projectMemberId - ?: getString(R.string.not_logged_in)) - login!!.visibility = if (projectMemberId == null) View.VISIBLE else View.GONE - logout!!.visibility = if (projectMemberId != null) View.VISIBLE else View.GONE - } - } - - object UpdateViewEvent : Event() - - object UpdateQueueEvent : Event() -} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OpenHumansLoginActivity.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OpenHumansLoginActivity.kt deleted file mode 100644 index ecb110d6dd..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/openhumans/OpenHumansLoginActivity.kt +++ /dev/null @@ -1,138 +0,0 @@ -package info.nightscout.androidaps.plugins.general.openhumans - -import android.app.Dialog -import android.content.Intent -import android.net.Uri -import android.os.Bundle -import android.widget.Button -import android.widget.CheckBox -import android.widget.Toast -import androidx.appcompat.app.AlertDialog -import androidx.browser.customtabs.CustomTabsIntent -import androidx.fragment.app.DialogFragment -import androidx.fragment.app.FragmentActivity -import dagger.android.support.DaggerDialogFragment -import info.nightscout.androidaps.R -import info.nightscout.androidaps.activities.NoSplashAppCompatActivity -import info.nightscout.androidaps.utils.rx.AapsSchedulers -import io.reactivex.disposables.Disposable -import javax.inject.Inject - -class OpenHumansLoginActivity : NoSplashAppCompatActivity() { - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.activity_open_humans_login) - val button = findViewById