From 6c0853d49a8849d9a37211b6ed12ec368d8f0272 Mon Sep 17 00:00:00 2001 From: AdrianLxM Date: Wed, 10 Apr 2019 00:33:05 +0200 Subject: [PATCH 01/20] kotlin support --- app/build.gradle | 7 +++++++ build.gradle | 2 ++ 2 files changed, 9 insertions(+) diff --git a/app/build.gradle b/app/build.gradle index 5cdb5bfd6a..8637ac27d8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -10,6 +10,8 @@ buildscript { } } apply plugin: "com.android.application" +apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-android' apply plugin: 'com.google.gms.google-services' apply plugin: "io.fabric" apply plugin: "jacoco-android" @@ -27,6 +29,7 @@ ext { repositories { maven { url 'https://maven.fabric.io/public' } jcenter { url "https://jcenter.bintray.com/" } + mavenCentral() } def generateGitBuild = { -> @@ -75,6 +78,9 @@ android { moduleName "BleCommandUtil" } } + kotlinOptions { + jvmTarget = '1.8' + } lintOptions { // TODO remove once wear dependency com.google.android.gms:play-services-wearable:7.3.0 // has been upgraded (requiring significant code changes), which currently fails release @@ -233,6 +239,7 @@ dependencies { androidTestImplementation "org.mockito:mockito-core:2.8.47" androidTestImplementation "com.google.dexmaker:dexmaker:${dexmakerVersion}" androidTestImplementation "com.google.dexmaker:dexmaker-mockito:${dexmakerVersion}" + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" } task unzip(type: Copy) { diff --git a/build.gradle b/build.gradle index 57745d34ab..6826c29a13 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { + ext.kotlin_version = '1.3.21' repositories { google() jcenter() @@ -16,6 +17,7 @@ buildscript { // in the individual module build.gradle files classpath 'com.jakewharton:butterknife-gradle-plugin:9.0.0-SNAPSHOT' + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } From bd5d31a4a31f290bbba304dd8b321c5b24a161bd Mon Sep 17 00:00:00 2001 From: AdrianLxM Date: Wed, 10 Apr 2019 00:36:02 +0200 Subject: [PATCH 02/20] check version Java -> Kotlin --- .../nightscout/androidaps/MainActivity.java | 4 +- .../versionChecker/VersionCheckerUtils.kt | 63 +++++++++++ .../androidaps/utils/VersionChecker.java | 100 ------------------ 3 files changed, 65 insertions(+), 102 deletions(-) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtils.kt delete mode 100644 app/src/main/java/info/nightscout/androidaps/utils/VersionChecker.java diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.java b/app/src/main/java/info/nightscout/androidaps/MainActivity.java index f441a8b243..7ce5ae2beb 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.java @@ -51,6 +51,7 @@ import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus; +import info.nightscout.androidaps.plugins.general.versionChecker.VersionCheckerUtilsKt; import info.nightscout.androidaps.setupwizard.SetupWizardActivity; import info.nightscout.androidaps.tabs.TabPageAdapter; import info.nightscout.androidaps.utils.AndroidPermission; @@ -59,7 +60,6 @@ import info.nightscout.androidaps.utils.LocaleHelper; import info.nightscout.androidaps.utils.OKDialog; import info.nightscout.androidaps.utils.PasswordProtection; import info.nightscout.androidaps.utils.SP; -import info.nightscout.androidaps.utils.VersionChecker; public class MainActivity extends AppCompatActivity { private static Logger log = LoggerFactory.getLogger(L.CORE); @@ -115,7 +115,7 @@ public class MainActivity extends AppCompatActivity { public void onPageScrollStateChanged(int state) { } }); - VersionChecker.check(); + VersionCheckerUtilsKt.checkVersion(); FabricPrivacy.setUserStats(); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtils.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtils.kt new file mode 100644 index 0000000000..e2d79e99a9 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtils.kt @@ -0,0 +1,63 @@ +package info.nightscout.androidaps.plugins.general.versionChecker + +import android.content.Context +import android.net.ConnectivityManager +import info.nightscout.androidaps.BuildConfig +import info.nightscout.androidaps.MainApp +import info.nightscout.androidaps.R +import info.nightscout.androidaps.logging.L +import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification +import info.nightscout.androidaps.plugins.general.overview.notifications.Notification +import org.apache.http.HttpResponse +import org.apache.http.client.methods.HttpGet +import org.apache.http.impl.client.DefaultHttpClient +import org.slf4j.LoggerFactory +import java.io.IOException +import java.io.InputStream + +// check network connection +fun isConnected(): Boolean { + val connMgr = MainApp.instance().applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + return connMgr.activeNetworkInfo?.isConnected ?: false +} + +// convert inputstream to String +@Throws(IOException::class) +fun InputStream.findVersion(): String? { + var version: String? = null + val regex = "(.*)version(.*)\"(((\\d+)\\.)+(\\d+))\"(.*)" + + this.bufferedReader().forEachLine { + if (regex.toRegex().matches(it)) { + version = regex.toRegex().matchEntire(it)?.groupValues?.getOrNull(3) + return@forEachLine + } + } + return version +} + +private val log = LoggerFactory.getLogger(L.CORE) + +@Suppress("DEPRECATION") +fun checkVersion() = if (isConnected()) { + Thread { + try { + val request = HttpGet("https://raw.githubusercontent.com/MilosKozak/AndroidAPS/master/app/build.gradle") + val response: HttpResponse = DefaultHttpClient().execute(request) + val version: String? = response.entity.content?.findVersion() + val comparison = version?.compareTo(BuildConfig.VERSION_NAME.replace("\"", "")) ?: 0 + if (comparison == 0) { + log.debug("Version equal to master of fetch failed") + } else if (comparison > 0) { + log.debug("Version outdated. Found $version") + val notification = Notification(Notification.NEWVERSIONDETECTED, String.format(MainApp.gs(R.string.versionavailable), version.toString()), Notification.LOW) + MainApp.bus().post(EventNewNotification(notification)) + } else { + log.debug("Version newer than master. Are you developer?") + } + } catch (e: IOException) { + log.debug("Github master version check error: $e") + } + }.start() +} else + log.debug("Github master version no checked. No connectivity") \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/utils/VersionChecker.java b/app/src/main/java/info/nightscout/androidaps/utils/VersionChecker.java deleted file mode 100644 index fd636b4596..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/utils/VersionChecker.java +++ /dev/null @@ -1,100 +0,0 @@ -package info.nightscout.androidaps.utils; - -import android.net.ConnectivityManager; -import android.net.NetworkInfo; - -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.impl.client.DefaultHttpClient; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import info.nightscout.androidaps.BuildConfig; -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.logging.L; -import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification; -import info.nightscout.androidaps.plugins.general.overview.notifications.Notification; - -import static android.content.Context.CONNECTIVITY_SERVICE; - -public class VersionChecker { - private static Logger log = LoggerFactory.getLogger(L.CORE); - - public static void check() { - if (isConnected()) - new Thread(() -> { - HttpClient client = new DefaultHttpClient(); - HttpGet request = new HttpGet("https://raw.githubusercontent.com/MilosKozak/AndroidAPS/master/app/build.gradle"); - HttpResponse response; - - try { - response = client.execute(request); - InputStream inputStream = response.getEntity().getContent(); - - if (inputStream != null) { - String result = findLine(inputStream); - if (result != null) { - int compare = result.compareTo(BuildConfig.VERSION_NAME.replace("\"", "")); - if (compare == 0) { - log.debug("Version equal to master"); - return; - } else if (compare > 0) { - log.debug("Version outdated. Found " + result); - Notification notification = new Notification(Notification.NEWVERSIONDETECTED, String.format(MainApp.gs(R.string.versionavailable), result), Notification.LOW); - MainApp.bus().post(new EventNewNotification(notification)); - return; - } else { - log.debug("Version newer than master. Are you developer?"); - return; - } - } - } - - log.debug("Github master version not found"); - - } catch (IOException e) { - e.printStackTrace(); - log.debug("Github master version check error"); - } - }).start(); - else - log.debug("Github master version no checked. No connectivity"); - } - - // convert inputstream to String - private static String findLine(InputStream inputStream) throws IOException { - BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream)); - String line; - String regex = "(.*)version(.*)\"(((\\d+)\\.)+(\\d+))\"(.*)"; - Pattern p = Pattern.compile(regex); - - while ((line = bufferedReader.readLine()) != null) { - Matcher m = p.matcher(line); - if (m.matches()) { - log.debug("+++ " + line); - return m.group(3); - } else { - log.debug("--- " + line); - } - } - inputStream.close(); - return null; - } - - // check network connection - public static boolean isConnected() { - ConnectivityManager connMgr = (ConnectivityManager) MainApp.instance().getApplicationContext().getSystemService(CONNECTIVITY_SERVICE); - NetworkInfo networkInfo = connMgr.getActiveNetworkInfo(); - return networkInfo != null && networkInfo.isConnected(); - } - -} From c34cf576e5f386b3872ecafd34fb41c4ba62aeff Mon Sep 17 00:00:00 2001 From: AdrianLxM Date: Wed, 10 Apr 2019 00:41:48 +0200 Subject: [PATCH 03/20] VersionCheckerPlugin nightly stub --- .../versionChecker/VersionCheckerPlugin.kt | 22 +++++++++++++++++++ app/src/main/res/values/strings.xml | 1 + 2 files changed, 23 insertions(+) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerPlugin.kt diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerPlugin.kt new file mode 100644 index 0000000000..99268bcdd9 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerPlugin.kt @@ -0,0 +1,22 @@ +package info.nightscout.androidaps.plugins.general.versionChecker + +import info.nightscout.androidaps.R +import info.nightscout.androidaps.interfaces.* + +/** + * Usually we would have a class here. + * Instead of having a class we can use an object directly inherited from PluginBase. + * This is a lazy loading singleton only loaded when actually used. + * */ + +object VersionCheckerPlugin : PluginBase(PluginDescription() + .mainType(PluginType.CONSTRAINTS) + .neverVisible(true) + .alwaysEnabled(true) + .showInList(false) + .pluginName(R.string.versionChecker)), ConstraintsInterface { + + override fun isClosedLoopAllowed(value: Constraint): Constraint { + return value + } +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 79d626f9be..3d7d2a3c60 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1326,6 +1326,7 @@ Wrong code. Command cancelled. Not configured Profile switch created + Version Checker %1$d day %1$d days From 85cc61934cc33a7f6316e52d50908918d5dbddeb Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Wed, 10 Apr 2019 14:49:23 +0200 Subject: [PATCH 04/20] add test --- .../VersionCheckerUtilsKtTest.kt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt new file mode 100644 index 0000000000..237012e74c --- /dev/null +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt @@ -0,0 +1,19 @@ +package info.nightscout.androidaps.plugins.general.versionChecker + +import org.junit.Assert.assertEquals +import org.junit.Test + +class VersionCheckerUtilsKtTest { + @Test + fun findVersionMatches() { + val buildGradle = """blabla + | android { + | aosenuthoae + | } + | version = "2.2.2" + | appName = "Aaoeu" + """.trimMargin() + val detectedVersion: String? = buildGradle.byteInputStream().findVersion() + assertEquals("2.2.2", detectedVersion) + } +} \ No newline at end of file From a33afc99f611cc581251cf4d258da27ef191b606 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Wed, 10 Apr 2019 14:50:26 +0200 Subject: [PATCH 05/20] JUST PLAYING AROUND --- .../versionChecker/VersionCheckerUtils.kt | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtils.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtils.kt index e2d79e99a9..a7d167d801 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtils.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtils.kt @@ -24,16 +24,12 @@ fun isConnected(): Boolean { // convert inputstream to String @Throws(IOException::class) fun InputStream.findVersion(): String? { - var version: String? = null - val regex = "(.*)version(.*)\"(((\\d+)\\.)+(\\d+))\"(.*)" - - this.bufferedReader().forEachLine { - if (regex.toRegex().matches(it)) { - version = regex.toRegex().matchEntire(it)?.groupValues?.getOrNull(3) - return@forEachLine - } - } - return version + val regex = "(.*)version(.*)\"(((\\d+)\\.)+(\\d+))\"(.*)".toRegex() + return bufferedReader() + .readLines() + .filter { regex.matches(it) } + .mapNotNull { regex.matchEntire(it)?.groupValues?.getOrNull(3) } + .firstOrNull() } private val log = LoggerFactory.getLogger(L.CORE) From cefee4827bd37d5745b06a515fabe1a958cc7502 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Wed, 10 Apr 2019 14:58:01 +0200 Subject: [PATCH 06/20] TDDing --- .../VersionCheckerUtilsKtTest.kt | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt index 237012e74c..d5af3a9409 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt @@ -5,7 +5,7 @@ import org.junit.Test class VersionCheckerUtilsKtTest { @Test - fun findVersionMatches() { + fun findVersionMatchesRegularVersion() { val buildGradle = """blabla | android { | aosenuthoae @@ -16,4 +16,25 @@ class VersionCheckerUtilsKtTest { val detectedVersion: String? = buildGradle.byteInputStream().findVersion() assertEquals("2.2.2", detectedVersion) } + + // 04. Break stuff.mp3 like it's 1999. Again. Pizza delivery! For i c wiener ... + //@Test + fun findVersionMatchesCustomVersion() { + val buildGradle = """blabla + | android { + | aosenuthoae + | } + | version = "2.2.2-nefarious-underground-mod" + | appName = "Aaoeu" + """.trimMargin() + val detectedVersion: String? = buildGradle.byteInputStream().findVersion() + assertEquals("2.2.2", detectedVersion) + } + + @Test + fun findVersionMatchesDoesNotMatchErrorResponse() { + val buildGradle = """Balls! No build.gradle here. Move along""" + val detectedVersion: String? = buildGradle.byteInputStream().findVersion() + assertEquals(null, detectedVersion) + } } \ No newline at end of file From d786a2a89871ce75846bd4e272cea6ef90397226 Mon Sep 17 00:00:00 2001 From: Tebbe Ubben Date: Wed, 10 Apr 2019 16:15:18 +0200 Subject: [PATCH 07/20] Insight: Set SQLite Sequence to current time millis on table creation --- .../java/info/nightscout/androidaps/db/DatabaseHelper.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java index c23d797c8c..b024f64711 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java @@ -131,6 +131,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { TableUtils.createTableIfNotExists(connectionSource, InsightHistoryOffset.class); TableUtils.createTableIfNotExists(connectionSource, InsightBolusID.class); TableUtils.createTableIfNotExists(connectionSource, InsightPumpID.class); + database.execSQL("UPDATE SQLITE_SEQUENCE SET seq = " + System.currentTimeMillis() + " WHERE name = " + DATABASE_INSIGHT_BOLUS_IDS); + database.execSQL("UPDATE SQLITE_SEQUENCE SET seq = " + System.currentTimeMillis() + " WHERE name = " + DATABASE_INSIGHT_PUMP_IDS); } catch (SQLException e) { log.error("Can't create database", e); throw new RuntimeException(e); @@ -151,6 +153,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { TableUtils.createTableIfNotExists(connectionSource, InsightHistoryOffset.class); TableUtils.createTableIfNotExists(connectionSource, InsightBolusID.class); TableUtils.createTableIfNotExists(connectionSource, InsightPumpID.class); + database.execSQL("UPDATE SQLITE_SEQUENCE SET seq = " + System.currentTimeMillis() + " WHERE name = " + DATABASE_INSIGHT_BOLUS_IDS); + database.execSQL("UPDATE SQLITE_SEQUENCE SET seq = " + System.currentTimeMillis() + " WHERE name = " + DATABASE_INSIGHT_PUMP_IDS); } else { log.info(DatabaseHelper.class.getName(), "onUpgrade"); TableUtils.dropTable(connectionSource, TempTarget.class, true); From 04618156cc03c50bf901f0d9d8afb1ca4c9d2168 Mon Sep 17 00:00:00 2001 From: AdrianLxM Date: Thu, 11 Apr 2019 12:43:52 +0200 Subject: [PATCH 08/20] restructure and test version checker --- .../versionChecker/VersionCheckerUtils.kt | 36 +++++--- .../VersionCheckerUtilsKtTest.kt | 88 ++++++++++++++++++- 2 files changed, 108 insertions(+), 16 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtils.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtils.kt index a7d167d801..c1378451df 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtils.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtils.kt @@ -23,7 +23,7 @@ fun isConnected(): Boolean { // convert inputstream to String @Throws(IOException::class) -fun InputStream.findVersion(): String? { +inline fun InputStream.findVersion(): String? { val regex = "(.*)version(.*)\"(((\\d+)\\.)+(\\d+))\"(.*)".toRegex() return bufferedReader() .readLines() @@ -41,19 +41,31 @@ fun checkVersion() = if (isConnected()) { val request = HttpGet("https://raw.githubusercontent.com/MilosKozak/AndroidAPS/master/app/build.gradle") val response: HttpResponse = DefaultHttpClient().execute(request) val version: String? = response.entity.content?.findVersion() - val comparison = version?.compareTo(BuildConfig.VERSION_NAME.replace("\"", "")) ?: 0 - if (comparison == 0) { - log.debug("Version equal to master of fetch failed") - } else if (comparison > 0) { - log.debug("Version outdated. Found $version") - val notification = Notification(Notification.NEWVERSIONDETECTED, String.format(MainApp.gs(R.string.versionavailable), version.toString()), Notification.LOW) - MainApp.bus().post(EventNewNotification(notification)) - } else { - log.debug("Version newer than master. Are you developer?") - } + compareWithCurrentVersion(version, BuildConfig.VERSION_NAME) } catch (e: IOException) { log.debug("Github master version check error: $e") } }.start() } else - log.debug("Github master version no checked. No connectivity") \ No newline at end of file + log.debug("Github master version no checked. No connectivity") + +fun compareWithCurrentVersion(newVersion: String?, currentVersion: String) { + val comparison = newVersion?.versionStrip()?.compareTo(currentVersion.versionStrip()) ?: 0 + when { + comparison == 0 -> log.debug("Version equal to master of fetch failed") + comparison > 0 -> { + log.debug("Version ${currentVersion} outdated. Found $newVersion") + val notification = Notification(Notification.NEWVERSIONDETECTED, String.format(MainApp.gs(R.string.versionavailable), newVersion.toString()), Notification.LOW) + MainApp.bus().post(EventNewNotification(notification)) + } + else -> log.debug("Version newer than master. Are you developer?") + } +} + + fun String.versionStrip() = this.mapNotNull { + when (it) { + in '0'..'9' -> it + '.' -> it + else -> null + } + }.joinToString (separator = "") \ No newline at end of file diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt index d5af3a9409..503c8d46be 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt @@ -1,8 +1,18 @@ package info.nightscout.androidaps.plugins.general.versionChecker +import com.squareup.otto.Bus +import info.nightscout.androidaps.MainApp +import info.nightscout.androidaps.logging.L import org.junit.Assert.assertEquals import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers +import org.mockito.Mockito.* +import org.powermock.api.mockito.PowerMockito +import org.powermock.core.classloader.annotations.PrepareForTest +import org.powermock.modules.junit4.PowerMockRunner +@RunWith(PowerMockRunner::class) class VersionCheckerUtilsKtTest { @Test fun findVersionMatchesRegularVersion() { @@ -17,9 +27,10 @@ class VersionCheckerUtilsKtTest { assertEquals("2.2.2", detectedVersion) } - // 04. Break stuff.mp3 like it's 1999. Again. Pizza delivery! For i c wiener ... - //@Test - fun findVersionMatchesCustomVersion() { + + // In case we merge a "x.x.x-dev" into master, don't see it as update. + @Test + fun `should return null on non-digit versions on master`() { val buildGradle = """blabla | android { | aosenuthoae @@ -28,7 +39,7 @@ class VersionCheckerUtilsKtTest { | appName = "Aaoeu" """.trimMargin() val detectedVersion: String? = buildGradle.byteInputStream().findVersion() - assertEquals("2.2.2", detectedVersion) + assertEquals(null, detectedVersion) } @Test @@ -37,4 +48,73 @@ class VersionCheckerUtilsKtTest { val detectedVersion: String? = buildGradle.byteInputStream().findVersion() assertEquals(null, detectedVersion) } + + @Test + fun testVersionStrip() { + assertEquals("2.2.2", "2.2.2".versionStrip()) + assertEquals("2.2.2", "2.2.2-dev".versionStrip()) + assertEquals("2.2.2", "2.2.2dev".versionStrip()) + assertEquals("2.2.2", """"2.2.2"""".versionStrip()) + } + + @Test + @PrepareForTest(MainApp::class, L::class) + fun `should find update1`() { + val bus = prepareCompareTests() + compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.2.1") + verify(bus, times(1)).post(any()) + } + + @Test + @PrepareForTest(MainApp::class, L::class) + fun `should find update2`() { + val bus = prepareCompareTests() + compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.2.1-dev") + verify(bus, times(1)).post(any()) + } + + @Test + @PrepareForTest(MainApp::class, L::class) + fun `should find update3`() { + val bus = prepareCompareTests() + compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.1") + verify(bus, times(1)).post(any()) + } + + @Test + @PrepareForTest(MainApp::class, L::class) + fun `should find update4`() { + val bus = prepareCompareTests() + + compareWithCurrentVersion(newVersion = "2.2", currentVersion = "2.1.1") + + verify(bus, times(1)).post(any()) + } + + @Test + @PrepareForTest(MainApp::class, L::class) + fun `should find update5`() { + val bus = prepareCompareTests() + compareWithCurrentVersion(newVersion = "2.2.1", currentVersion = "2.2-dev") + verify(bus, times(1)).post(any()) + } + + @Test + @PrepareForTest(MainApp::class, L::class) + fun `should find update6`() { + val bus = prepareCompareTests() + compareWithCurrentVersion(newVersion = "2.2.1", currentVersion = "2.2dev") + verify(bus, times(1)).post(any()) + } + + + private fun prepareCompareTests(): Bus { + PowerMockito.mockStatic(MainApp::class.java) + val mainApp = mock(MainApp::class.java) + `when`(MainApp.instance()).thenReturn(mainApp) + val bus = mock(Bus::class.java) + `when`(MainApp.bus()).thenReturn(bus) + `when`(MainApp.gs(ArgumentMatchers.anyInt())).thenReturn("some dummy string") + return bus + } } \ No newline at end of file From f739980988cf54571733cf14291af0e39d359bdd Mon Sep 17 00:00:00 2001 From: AdrianLxM Date: Mon, 15 Apr 2019 08:04:56 +0200 Subject: [PATCH 09/20] testing and SP logic --- .../versionChecker/VersionCheckerUtils.kt | 41 +++++++---- app/src/main/res/values/strings.xml | 1 + .../VersionCheckerUtilsKtTest.kt | 71 +++++++++++++++---- 3 files changed, 86 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtils.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtils.kt index c1378451df..b8cfa7fffc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtils.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtils.kt @@ -8,6 +8,7 @@ import info.nightscout.androidaps.R import info.nightscout.androidaps.logging.L import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification +import info.nightscout.androidaps.utils.SP import org.apache.http.HttpResponse import org.apache.http.client.methods.HttpGet import org.apache.http.impl.client.DefaultHttpClient @@ -50,22 +51,34 @@ fun checkVersion() = if (isConnected()) { log.debug("Github master version no checked. No connectivity") fun compareWithCurrentVersion(newVersion: String?, currentVersion: String) { - val comparison = newVersion?.versionStrip()?.compareTo(currentVersion.versionStrip()) ?: 0 + val comparison: Int? = newVersion?.versionStrip()?.compareTo(currentVersion.versionStrip()) when { - comparison == 0 -> log.debug("Version equal to master of fetch failed") - comparison > 0 -> { - log.debug("Version ${currentVersion} outdated. Found $newVersion") - val notification = Notification(Notification.NEWVERSIONDETECTED, String.format(MainApp.gs(R.string.versionavailable), newVersion.toString()), Notification.LOW) - MainApp.bus().post(EventNewNotification(notification)) - } + comparison == null -> onVersionNotDetectable() + comparison == 0 -> onSameVersionDetected() + comparison > 0 -> onNewVersionDetected(currentVersion = currentVersion, newVersion = newVersion) else -> log.debug("Version newer than master. Are you developer?") } } - fun String.versionStrip() = this.mapNotNull { - when (it) { - in '0'..'9' -> it - '.' -> it - else -> null - } - }.joinToString (separator = "") \ No newline at end of file +fun onSameVersionDetected() { + SP.remove(R.string.key_new_version_available_since) +} + +fun onVersionNotDetectable() { + log.debug("fetch failed, ignore and smartcast to non-null") +} + +fun onNewVersionDetected(currentVersion: String, newVersion: String?) { + log.debug("Version ${currentVersion} outdated. Found $newVersion") + val notification = Notification(Notification.NEWVERSIONDETECTED, String.format(MainApp.gs(R.string.versionavailable), newVersion.toString()), Notification.LOW) + MainApp.bus().post(EventNewNotification(notification)) + SP.putLong(R.string.key_new_version_available_since, System.currentTimeMillis()) +} + +fun String.versionStrip() = this.mapNotNull { + when (it) { + in '0'..'9' -> it + '.' -> it + else -> null + } +}.joinToString(separator = "") \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3d7d2a3c60..feaab74c41 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1327,6 +1327,7 @@ Not configured Profile switch created Version Checker + new_version_available_since %1$d day %1$d days diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt index 503c8d46be..b1b62b589d 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt @@ -2,7 +2,9 @@ package info.nightscout.androidaps.plugins.general.versionChecker import com.squareup.otto.Bus import info.nightscout.androidaps.MainApp +import info.nightscout.androidaps.R import info.nightscout.androidaps.logging.L +import info.nightscout.androidaps.utils.SP import org.junit.Assert.assertEquals import org.junit.Test import org.junit.runner.RunWith @@ -58,33 +60,33 @@ class VersionCheckerUtilsKtTest { } @Test - @PrepareForTest(MainApp::class, L::class) + @PrepareForTest(MainApp::class, L::class, SP::class) fun `should find update1`() { - val bus = prepareCompareTests() + val bus = prepareBus() compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.2.1") verify(bus, times(1)).post(any()) } @Test - @PrepareForTest(MainApp::class, L::class) + @PrepareForTest(MainApp::class, L::class, SP::class) fun `should find update2`() { - val bus = prepareCompareTests() + val bus = prepareBus() compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.2.1-dev") verify(bus, times(1)).post(any()) } @Test - @PrepareForTest(MainApp::class, L::class) + @PrepareForTest(MainApp::class, L::class, SP::class) fun `should find update3`() { - val bus = prepareCompareTests() + val bus = prepareBus() compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.1") verify(bus, times(1)).post(any()) } @Test - @PrepareForTest(MainApp::class, L::class) + @PrepareForTest(MainApp::class, L::class, SP::class) fun `should find update4`() { - val bus = prepareCompareTests() + val bus = prepareBus() compareWithCurrentVersion(newVersion = "2.2", currentVersion = "2.1.1") @@ -92,29 +94,72 @@ class VersionCheckerUtilsKtTest { } @Test - @PrepareForTest(MainApp::class, L::class) + @PrepareForTest(MainApp::class, L::class, SP::class) fun `should find update5`() { - val bus = prepareCompareTests() + val bus = prepareBus() compareWithCurrentVersion(newVersion = "2.2.1", currentVersion = "2.2-dev") verify(bus, times(1)).post(any()) } @Test - @PrepareForTest(MainApp::class, L::class) + @PrepareForTest(MainApp::class, L::class, SP::class) fun `should find update6`() { - val bus = prepareCompareTests() + val bus = prepareBus() + val sp = prepareSP() compareWithCurrentVersion(newVersion = "2.2.1", currentVersion = "2.2dev") verify(bus, times(1)).post(any()) } + @Test + @PrepareForTest(MainApp::class, L::class, SP::class) + fun `find same version`() { + val buildGradle = """blabla + | android { + | aosenuthoae + | } + | version = "2.2.2" + | appName = "Aaoeu" + """.trimMargin() + val bus = prepareBus() + compareWithCurrentVersion(buildGradle.byteInputStream().findVersion(), currentVersion = "2.2.2") + verify(bus, times(0)).post(any()) + verify(SP, times(1)).remove(R.string.key_new_version_available_since) + } - private fun prepareCompareTests(): Bus { + @Test + @PrepareForTest(MainApp::class, L::class, SP::class) + fun `find higher version`() { + val buildGradle = """blabla + | android { + | aosenuthoae + | } + | version = "3.0" + | appName = "Aaoeu" + """.trimMargin() + val bus = prepareBus() + compareWithCurrentVersion(buildGradle.byteInputStream().findVersion(), currentVersion = "2.2.2") + verify(bus, times(1)).post(any()) + } + + + private fun prepareBus(): Bus { PowerMockito.mockStatic(MainApp::class.java) val mainApp = mock(MainApp::class.java) `when`(MainApp.instance()).thenReturn(mainApp) val bus = mock(Bus::class.java) `when`(MainApp.bus()).thenReturn(bus) `when`(MainApp.gs(ArgumentMatchers.anyInt())).thenReturn("some dummy string") + prepareSP() return bus } + + private fun prepareSP() { + PowerMockito.mockStatic(SP::class.java) + } + + private fun prepareLogging() { + PowerMockito.mockStatic(L::class.java) + `when`(L.isEnabled(any())).thenReturn(true) + } + } \ No newline at end of file From 78f2da405f975a13820a217d89a2d9b6a8f71535 Mon Sep 17 00:00:00 2001 From: Lee Braiden Date: Mon, 15 Apr 2019 19:09:56 +0100 Subject: [PATCH 10/20] Fix potential NPE in AlarmSoundService destructor. --- .../nightscout/androidaps/services/AlarmSoundService.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/services/AlarmSoundService.java b/app/src/main/java/info/nightscout/androidaps/services/AlarmSoundService.java index e95cd7c479..4917789db1 100644 --- a/app/src/main/java/info/nightscout/androidaps/services/AlarmSoundService.java +++ b/app/src/main/java/info/nightscout/androidaps/services/AlarmSoundService.java @@ -75,8 +75,11 @@ public class AlarmSoundService extends Service { @Override public void onDestroy() { - player.stop(); - player.release(); + if (player != null) { + player.stop(); + player.release(); + } + if (L.isEnabled(L.CORE)) log.debug("onDestroy"); } From 952a6fe5097ee67a92157ecb0233abeb730f0651 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 16 Apr 2019 20:36:18 +0200 Subject: [PATCH 11/20] fix GlucoseStatus calculation --- .../androidaps/data/GlucoseStatus.java | 178 ----------------- .../androidaps/data/QuickWizardEntry.java | 1 + .../DetermineBasalAdapterAMAJS.java | 2 +- .../aps/openAPSAMA/OpenAPSAMAPlugin.java | 2 +- .../openAPSMA/DetermineBasalAdapterMAJS.java | 2 +- .../aps/openAPSMA/OpenAPSMAPlugin.java | 2 +- .../DetermineBasalAdapterSMBJS.java | 2 +- .../aps/openAPSSMB/OpenAPSSMBPlugin.java | 2 +- .../Dialogs/NewNSTreatmentDialog.java | 2 +- .../general/overview/OverviewFragment.java | 2 +- .../overview/dialogs/CalibrationDialog.java | 2 +- .../PersistentNotificationPlugin.java | 2 +- .../SmsCommunicatorPlugin.java | 2 +- .../wearintegration/WatchUpdaterService.java | 12 +- .../iob/iobCobCalculator/GlucoseStatus.java | 180 ++++++++++++++++++ .../androidaps/utils/BolusWizard.java | 2 +- .../androidaps/data/GlucoseStatusTest.java | 1 + .../androidaps/utils/BolusWizardTest.java | 2 +- 18 files changed, 196 insertions(+), 202 deletions(-) delete mode 100644 app/src/main/java/info/nightscout/androidaps/data/GlucoseStatus.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatus.java diff --git a/app/src/main/java/info/nightscout/androidaps/data/GlucoseStatus.java b/app/src/main/java/info/nightscout/androidaps/data/GlucoseStatus.java deleted file mode 100644 index be3e981fb4..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/data/GlucoseStatus.java +++ /dev/null @@ -1,178 +0,0 @@ -package info.nightscout.androidaps.data; - -import android.support.annotation.Nullable; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; - -import info.nightscout.androidaps.db.BgReading; -import info.nightscout.androidaps.logging.L; -import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; -import info.nightscout.androidaps.utils.DateUtil; -import info.nightscout.androidaps.utils.DecimalFormatter; -import info.nightscout.androidaps.utils.Round; - -/** - * Created by mike on 04.01.2017. - */ - -public class GlucoseStatus { - private static Logger log = LoggerFactory.getLogger(GlucoseStatus.class); - public double glucose = 0d; - public double delta = 0d; - public double avgdelta = 0d; - public double short_avgdelta = 0d; - public double long_avgdelta = 0d; - public long date = 0L; - - - public String log() { - return "Glucose: " + DecimalFormatter.to0Decimal(glucose) + " mg/dl " + - "Delta: " + DecimalFormatter.to0Decimal(delta) + " mg/dl" + - "Short avg. delta: " + " " + DecimalFormatter.to2Decimal(short_avgdelta) + " mg/dl " + - "Long avg. delta: " + DecimalFormatter.to2Decimal(long_avgdelta) + " mg/dl"; - } - - public GlucoseStatus() { - } - - public GlucoseStatus round() { - this.glucose = Round.roundTo(this.glucose, 0.1); - this.delta = Round.roundTo(this.delta, 0.01); - this.avgdelta = Round.roundTo(this.avgdelta, 0.01); - this.short_avgdelta = Round.roundTo(this.short_avgdelta, 0.01); - this.long_avgdelta = Round.roundTo(this.long_avgdelta, 0.01); - return this; - } - - - @Nullable - public static GlucoseStatus getGlucoseStatusData() { - return getGlucoseStatusData(false); - } - - @Nullable - public static GlucoseStatus getGlucoseStatusData(boolean allowOldData) { - // load 45min - //long fromtime = DateUtil.now() - 60 * 1000L * 45; - //List data = MainApp.getDbHelper().getBgreadingsDataFromTime(fromtime, false); - - List data = IobCobCalculatorPlugin.getPlugin().getBgReadings(); - - if (data == null) { - if (L.isEnabled(L.GLUCOSE)) - log.debug("data=null"); - return null; - } - - int sizeRecords = data.size(); - if (sizeRecords == 0) { - if (L.isEnabled(L.GLUCOSE)) - log.debug("sizeRecords==0"); - return null; - } - - if (data.get(0).date < DateUtil.now() - 7 * 60 * 1000L && !allowOldData) { - if (L.isEnabled(L.GLUCOSE)) - log.debug("olddata"); - return null; - } - - BgReading now = data.get(0); - long now_date = now.date; - double change; - - if (sizeRecords == 1) { - GlucoseStatus status = new GlucoseStatus(); - status.glucose = now.value; - status.short_avgdelta = 0d; - status.delta = 0d; - status.long_avgdelta = 0d; - status.avgdelta = 0d; // for OpenAPS MA - status.date = now_date; - if (L.isEnabled(L.GLUCOSE)) - log.debug("sizeRecords==1"); - return status.round(); - } - - ArrayList now_value_list = new ArrayList<>(); - ArrayList last_deltas = new ArrayList<>(); - ArrayList short_deltas = new ArrayList<>(); - ArrayList long_deltas = new ArrayList<>(); - - // Use the latest sgv value in the now calculations - now_value_list.add(now.value); - - for (int i = 1; i < sizeRecords; i++) { - if (data.get(i).value > 38) { - BgReading then = data.get(i); - long then_date = then.date; - double avgdelta; - long minutesago; - - minutesago = Math.round((now_date - then_date) / (1000d * 60)); - // multiply by 5 to get the same units as delta, i.e. mg/dL/5m - change = now.value - then.value; - avgdelta = change / minutesago * 5; - - if (L.isEnabled(L.GLUCOSE)) - log.debug(then.toString() + " minutesago=" + minutesago + " avgdelta=" + avgdelta); - - // use the average of all data points in the last 2.5m for all further "now" calculations - if (0 < minutesago && minutesago < 2.5) { - // Keep and average all values within the last 2.5 minutes - now_value_list.add(then.value); - now.value = average(now_value_list); - // short_deltas are calculated from everything ~5-15 minutes ago - } else if (2.5 < minutesago && minutesago < 17.5) { - //console.error(minutesago, avgdelta); - short_deltas.add(avgdelta); - // last_deltas are calculated from everything ~5 minutes ago - if (2.5 < minutesago && minutesago < 7.5) { - last_deltas.add(avgdelta); - } - // long_deltas are calculated from everything ~20-40 minutes ago - } else if (17.5 < minutesago && minutesago < 42.5) { - long_deltas.add(avgdelta); - } else { - // Do not process any more records after >= 42.5 minutes - break; - } - } - } - - GlucoseStatus status = new GlucoseStatus(); - status.glucose = now.value; - status.date = now_date; - - status.short_avgdelta = average(short_deltas); - - if (last_deltas.isEmpty()) { - status.delta = status.short_avgdelta; - } else { - status.delta = average(last_deltas); - } - - status.long_avgdelta = average(long_deltas); - status.avgdelta = status.short_avgdelta; // for OpenAPS MA - - if (L.isEnabled(L.GLUCOSE)) - log.debug(status.log()); - return status.round(); - } - - public static double average(ArrayList array) { - double sum = 0d; - - if (array.size() == 0) - return 0d; - - for (Double value : array) { - sum += value; - } - return sum / array.size(); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/data/QuickWizardEntry.java b/app/src/main/java/info/nightscout/androidaps/data/QuickWizardEntry.java index 4262fe2133..0bfcbb1002 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/QuickWizardEntry.java +++ b/app/src/main/java/info/nightscout/androidaps/data/QuickWizardEntry.java @@ -12,6 +12,7 @@ import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.interfaces.TreatmentsInterface; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/DetermineBasalAdapterAMAJS.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/DetermineBasalAdapterAMAJS.java index 7eb9a2d81d..5b5c8cb63d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/DetermineBasalAdapterAMAJS.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/DetermineBasalAdapterAMAJS.java @@ -20,7 +20,7 @@ import java.lang.reflect.InvocationTargetException; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.GlucoseStatus; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.Profile; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.java index 3447c7c4f4..1f7deebea4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSAMA/OpenAPSAMAPlugin.java @@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.GlucoseStatus; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.Profile; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/DetermineBasalAdapterMAJS.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/DetermineBasalAdapterMAJS.java index 4baabf22ab..ae1f390ded 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/DetermineBasalAdapterMAJS.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/DetermineBasalAdapterMAJS.java @@ -17,7 +17,7 @@ import java.lang.reflect.InvocationTargetException; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.GlucoseStatus; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.Profile; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/OpenAPSMAPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/OpenAPSMAPlugin.java index 24b4cb7929..2dd78bdb82 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/OpenAPSMAPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSMA/OpenAPSMAPlugin.java @@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.GlucoseStatus; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.Profile; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalAdapterSMBJS.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalAdapterSMBJS.java index edaddd62c9..bfb75503c1 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalAdapterSMBJS.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/DetermineBasalAdapterSMBJS.java @@ -20,7 +20,7 @@ import java.lang.reflect.InvocationTargetException; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.GlucoseStatus; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.Profile; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.java index 73914662d7..728e3145d6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/aps/openAPSSMB/OpenAPSSMBPlugin.java @@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.GlucoseStatus; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.MealData; import info.nightscout.androidaps.data.Profile; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/careportal/Dialogs/NewNSTreatmentDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/careportal/Dialogs/NewNSTreatmentDialog.java index e94cc658ca..57414927b4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/careportal/Dialogs/NewNSTreatmentDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/careportal/Dialogs/NewNSTreatmentDialog.java @@ -39,7 +39,7 @@ import java.util.List; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.GlucoseStatus; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.db.BgReading; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java index c4d8655ca8..6d41303540 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java @@ -56,7 +56,7 @@ import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; -import info.nightscout.androidaps.data.GlucoseStatus; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.QuickWizardEntry; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/CalibrationDialog.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/CalibrationDialog.java index 53c571aad7..0ab1b98ff6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/CalibrationDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/CalibrationDialog.java @@ -18,7 +18,7 @@ import java.text.DecimalFormat; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.GlucoseStatus; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.utils.NumberPicker; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/persistentNotification/PersistentNotificationPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/persistentNotification/PersistentNotificationPlugin.java index 0287c21260..987d9374bd 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/persistentNotification/PersistentNotificationPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/persistentNotification/PersistentNotificationPlugin.java @@ -20,7 +20,7 @@ import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainActivity; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.GlucoseStatus; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.DatabaseHelper; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index 7703561aa9..181bdd86d2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -20,7 +20,7 @@ import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; -import info.nightscout.androidaps.data.GlucoseStatus; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.ProfileStore; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java index 86b56ba130..d121c5c55d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/wear/wearintegration/WatchUpdaterService.java @@ -32,17 +32,11 @@ import com.google.android.gms.wearable.PutDataRequest; import com.google.android.gms.wearable.Wearable; import com.google.android.gms.wearable.WearableListenerService; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; - import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.GlucoseStatus; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.BgReading; @@ -55,15 +49,11 @@ import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.TreatmentsInterface; import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus; import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler; import info.nightscout.androidaps.plugins.general.wear.WearPlugin; -import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; -import info.nightscout.androidaps.plugins.treatments.Treatment; -import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SafeParse; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatus.java new file mode 100644 index 0000000000..94fab37d8b --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatus.java @@ -0,0 +1,180 @@ +package info.nightscout.androidaps.plugins.iob.iobCobCalculator; + +import android.support.annotation.Nullable; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.List; + +import info.nightscout.androidaps.db.BgReading; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.utils.DateUtil; +import info.nightscout.androidaps.utils.DecimalFormatter; +import info.nightscout.androidaps.utils.Round; + +/** + * Created by mike on 04.01.2017. + */ + +public class GlucoseStatus { + private static Logger log = LoggerFactory.getLogger(GlucoseStatus.class); + public double glucose = 0d; + public double delta = 0d; + public double avgdelta = 0d; + public double short_avgdelta = 0d; + public double long_avgdelta = 0d; + public long date = 0L; + + + public String log() { + return "Glucose: " + DecimalFormatter.to0Decimal(glucose) + " mg/dl " + + "Delta: " + DecimalFormatter.to0Decimal(delta) + " mg/dl" + + "Short avg. delta: " + " " + DecimalFormatter.to2Decimal(short_avgdelta) + " mg/dl " + + "Long avg. delta: " + DecimalFormatter.to2Decimal(long_avgdelta) + " mg/dl"; + } + + public GlucoseStatus() { + } + + public GlucoseStatus round() { + this.glucose = Round.roundTo(this.glucose, 0.1); + this.delta = Round.roundTo(this.delta, 0.01); + this.avgdelta = Round.roundTo(this.avgdelta, 0.01); + this.short_avgdelta = Round.roundTo(this.short_avgdelta, 0.01); + this.long_avgdelta = Round.roundTo(this.long_avgdelta, 0.01); + return this; + } + + + @Nullable + public static GlucoseStatus getGlucoseStatusData() { + return getGlucoseStatusData(false); + } + + @Nullable + public static GlucoseStatus getGlucoseStatusData(boolean allowOldData) { + // load 45min + //long fromtime = DateUtil.now() - 60 * 1000L * 45; + //List data = MainApp.getDbHelper().getBgreadingsDataFromTime(fromtime, false); + + synchronized (IobCobCalculatorPlugin.getPlugin().dataLock) { + + List data = IobCobCalculatorPlugin.getPlugin().getBgReadings(); + + if (data == null) { + if (L.isEnabled(L.GLUCOSE)) + log.debug("data=null"); + return null; + } + + int sizeRecords = data.size(); + if (sizeRecords == 0) { + if (L.isEnabled(L.GLUCOSE)) + log.debug("sizeRecords==0"); + return null; + } + + if (data.get(0).date < DateUtil.now() - 7 * 60 * 1000L && !allowOldData) { + if (L.isEnabled(L.GLUCOSE)) + log.debug("olddata"); + return null; + } + + BgReading now = data.get(0); + long now_date = now.date; + double change; + + if (sizeRecords == 1) { + GlucoseStatus status = new GlucoseStatus(); + status.glucose = now.value; + status.short_avgdelta = 0d; + status.delta = 0d; + status.long_avgdelta = 0d; + status.avgdelta = 0d; // for OpenAPS MA + status.date = now_date; + if (L.isEnabled(L.GLUCOSE)) + log.debug("sizeRecords==1"); + return status.round(); + } + + ArrayList now_value_list = new ArrayList<>(); + ArrayList last_deltas = new ArrayList<>(); + ArrayList short_deltas = new ArrayList<>(); + ArrayList long_deltas = new ArrayList<>(); + + // Use the latest sgv value in the now calculations + now_value_list.add(now.value); + + for (int i = 1; i < sizeRecords; i++) { + if (data.get(i).value > 38) { + BgReading then = data.get(i); + long then_date = then.date; + double avgdelta; + long minutesago; + + minutesago = Math.round((now_date - then_date) / (1000d * 60)); + // multiply by 5 to get the same units as delta, i.e. mg/dL/5m + change = now.value - then.value; + avgdelta = change / minutesago * 5; + + if (L.isEnabled(L.GLUCOSE)) + log.debug(then.toString() + " minutesago=" + minutesago + " avgdelta=" + avgdelta); + + // use the average of all data points in the last 2.5m for all further "now" calculations + if (0 < minutesago && minutesago < 2.5) { + // Keep and average all values within the last 2.5 minutes + now_value_list.add(then.value); + now.value = average(now_value_list); + // short_deltas are calculated from everything ~5-15 minutes ago + } else if (2.5 < minutesago && minutesago < 17.5) { + //console.error(minutesago, avgdelta); + short_deltas.add(avgdelta); + // last_deltas are calculated from everything ~5 minutes ago + if (2.5 < minutesago && minutesago < 7.5) { + last_deltas.add(avgdelta); + } + // long_deltas are calculated from everything ~20-40 minutes ago + } else if (17.5 < minutesago && minutesago < 42.5) { + long_deltas.add(avgdelta); + } else { + // Do not process any more records after >= 42.5 minutes + break; + } + } + } + + GlucoseStatus status = new GlucoseStatus(); + status.glucose = now.value; + status.date = now_date; + + status.short_avgdelta = average(short_deltas); + + if (last_deltas.isEmpty()) { + status.delta = status.short_avgdelta; + } else { + status.delta = average(last_deltas); + } + + status.long_avgdelta = average(long_deltas); + status.avgdelta = status.short_avgdelta; // for OpenAPS MA + + if (L.isEnabled(L.GLUCOSE)) + log.debug(status.log()); + return status.round(); + } + } + + public static double average(ArrayList array) { + double sum = 0d; + + if (array.size() == 0) + return 0d; + + for (Double value : array) { + sum += value; + } + return sum / array.size(); + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/utils/BolusWizard.java b/app/src/main/java/info/nightscout/androidaps/utils/BolusWizard.java index e47a74e17f..cd789ee225 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/BolusWizard.java +++ b/app/src/main/java/info/nightscout/androidaps/utils/BolusWizard.java @@ -3,7 +3,7 @@ package info.nightscout.androidaps.utils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import info.nightscout.androidaps.data.GlucoseStatus; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.db.TempTarget; diff --git a/app/src/test/java/info/nightscout/androidaps/data/GlucoseStatusTest.java b/app/src/test/java/info/nightscout/androidaps/data/GlucoseStatusTest.java index 8bcdf0ed26..cdbd276bae 100644 --- a/app/src/test/java/info/nightscout/androidaps/data/GlucoseStatusTest.java +++ b/app/src/test/java/info/nightscout/androidaps/data/GlucoseStatusTest.java @@ -16,6 +16,7 @@ import java.util.List; import info.AAPSMocker; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.db.BgReading; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.general.nsclient.data.NSSgv; import info.nightscout.androidaps.utils.DateUtil; diff --git a/app/src/test/java/info/nightscout/androidaps/utils/BolusWizardTest.java b/app/src/test/java/info/nightscout/androidaps/utils/BolusWizardTest.java index 945c813674..2143a7101c 100644 --- a/app/src/test/java/info/nightscout/androidaps/utils/BolusWizardTest.java +++ b/app/src/test/java/info/nightscout/androidaps/utils/BolusWizardTest.java @@ -9,7 +9,7 @@ import org.powermock.modules.junit4.PowerMockRunner; import info.AAPSMocker; import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.data.GlucoseStatus; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.data.IobTotal; import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.interfaces.PumpInterface; From a6bd81a1b9f5bc77fc5329177dfb0cfed9f03857 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 16 Apr 2019 21:28:21 +0200 Subject: [PATCH 12/20] fix tests --- .../plugins/iob/iobCobCalculator/GlucoseStatus.java | 2 +- .../iob/iobCobCalculator/IobCobCalculatorPlugin.java | 6 +++++- .../plugins/iob/iobCobCalculator/IobCobOref1Thread.java | 2 +- .../plugins/iob/iobCobCalculator/IobCobThread.java | 2 +- app/src/test/java/info/AAPSMocker.java | 5 ++++- .../iob/iobCobCalculatorPlugin}/GlucoseStatusTest.java | 7 ++----- 6 files changed, 14 insertions(+), 10 deletions(-) rename app/src/test/java/info/nightscout/androidaps/{data => plugins/iob/iobCobCalculatorPlugin}/GlucoseStatusTest.java (97%) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatus.java index 94fab37d8b..191ce9e1cd 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatus.java @@ -59,7 +59,7 @@ public class GlucoseStatus { //long fromtime = DateUtil.now() - 60 * 1000L * 45; //List data = MainApp.getDbHelper().getBgreadingsDataFromTime(fromtime, false); - synchronized (IobCobCalculatorPlugin.getPlugin().dataLock) { + synchronized (IobCobCalculatorPlugin.getPlugin().getDataLock()) { List data = IobCobCalculatorPlugin.getPlugin().getBgReadings(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobCalculatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobCalculatorPlugin.java index 4897ff55ac..94b687b863 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobCalculatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobCalculatorPlugin.java @@ -65,7 +65,7 @@ public class IobCobCalculatorPlugin extends PluginBase { private volatile List bgReadings = null; // newest at index 0 private volatile List bucketed_data = null; - final Object dataLock = new Object(); + private final Object dataLock = new Object(); boolean stopCalculationTrigger = false; private Thread thread = null; @@ -108,6 +108,10 @@ public class IobCobCalculatorPlugin extends PluginBase { return bucketed_data; } + public Object getDataLock() { + return dataLock; + } + // roundup to whole minute public static long roundUpTime(long time) { if (time % 60000 == 0) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOref1Thread.java b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOref1Thread.java index 492f3c0ff1..c483ffd2a6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOref1Thread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobOref1Thread.java @@ -96,7 +96,7 @@ public class IobCobOref1Thread extends Thread { long oldestTimeWithData = iobCobCalculatorPlugin.calculateDetectionStart(end, limitDataToOldestAvailable); - synchronized (iobCobCalculatorPlugin.dataLock) { + synchronized (iobCobCalculatorPlugin.getDataLock()) { if (bgDataReload) { iobCobCalculatorPlugin.loadBgData(end); iobCobCalculatorPlugin.createBucketedData(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobThread.java b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobThread.java index 2aacb4f453..9ddf18abb0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobThread.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/IobCobThread.java @@ -95,7 +95,7 @@ public class IobCobThread extends Thread { long oldestTimeWithData = iobCobCalculatorPlugin.calculateDetectionStart(end, limitDataToOldestAvailable); - synchronized (iobCobCalculatorPlugin.dataLock) { + synchronized (iobCobCalculatorPlugin.getDataLock()) { if (bgDataReload) { iobCobCalculatorPlugin.loadBgData(end); iobCobCalculatorPlugin.createBucketedData(); diff --git a/app/src/test/java/info/AAPSMocker.java b/app/src/test/java/info/AAPSMocker.java index 850affa224..50bd20d198 100644 --- a/app/src/test/java/info/AAPSMocker.java +++ b/app/src/test/java/info/AAPSMocker.java @@ -282,10 +282,13 @@ public class AAPSMocker { PowerMockito.when(ProfileFunctions.getInstance().getProfileName()).thenReturn(TESTPROFILENAME); } - public static void mockIobCobCalculatorPlugin() { + public static IobCobCalculatorPlugin mockIobCobCalculatorPlugin() { PowerMockito.mockStatic(IobCobCalculatorPlugin.class); IobCobCalculatorPlugin iobCobCalculatorPlugin = PowerMockito.mock(IobCobCalculatorPlugin.class); PowerMockito.when(IobCobCalculatorPlugin.getPlugin()).thenReturn(iobCobCalculatorPlugin); + Object dataLock = new Object(); + PowerMockito.when(iobCobCalculatorPlugin.getDataLock()).thenReturn(dataLock); + return iobCobCalculatorPlugin; } private static MockedBus bus = new MockedBus(); diff --git a/app/src/test/java/info/nightscout/androidaps/data/GlucoseStatusTest.java b/app/src/test/java/info/nightscout/androidaps/plugins/iob/iobCobCalculatorPlugin/GlucoseStatusTest.java similarity index 97% rename from app/src/test/java/info/nightscout/androidaps/data/GlucoseStatusTest.java rename to app/src/test/java/info/nightscout/androidaps/plugins/iob/iobCobCalculatorPlugin/GlucoseStatusTest.java index cdbd276bae..19e497b834 100644 --- a/app/src/test/java/info/nightscout/androidaps/data/GlucoseStatusTest.java +++ b/app/src/test/java/info/nightscout/androidaps/plugins/iob/iobCobCalculatorPlugin/GlucoseStatusTest.java @@ -1,4 +1,4 @@ -package info.nightscout.androidaps.data; +package info.nightscout.androidaps.plugins.iob.iobCobCalculatorPlugin; import org.json.JSONException; import org.json.JSONObject; @@ -134,10 +134,7 @@ public class GlucoseStatusTest { public void initMocking() { AAPSMocker.mockMainApp(); AAPSMocker.mockStrings(); - - PowerMockito.mockStatic(IobCobCalculatorPlugin.class); - iobCobCalculatorPlugin = mock(IobCobCalculatorPlugin.class); - when(IobCobCalculatorPlugin.getPlugin()).thenReturn(iobCobCalculatorPlugin); + iobCobCalculatorPlugin = AAPSMocker.mockIobCobCalculatorPlugin(); PowerMockito.mockStatic(DateUtil.class); when(DateUtil.now()).thenReturn(1514766900000L + T.mins(1).msecs()); From 39412ae032acdd8a13b9364fca648ad584a946f6 Mon Sep 17 00:00:00 2001 From: Tebbe Ubben Date: Wed, 17 Apr 2019 17:31:10 +0200 Subject: [PATCH 13/20] Fix initial sqlite_sequence for Insight driver --- .../nightscout/androidaps/db/DatabaseHelper.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java index b024f64711..ad16cb90f6 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java +++ b/app/src/main/java/info/nightscout/androidaps/db/DatabaseHelper.java @@ -131,8 +131,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { TableUtils.createTableIfNotExists(connectionSource, InsightHistoryOffset.class); TableUtils.createTableIfNotExists(connectionSource, InsightBolusID.class); TableUtils.createTableIfNotExists(connectionSource, InsightPumpID.class); - database.execSQL("UPDATE SQLITE_SEQUENCE SET seq = " + System.currentTimeMillis() + " WHERE name = " + DATABASE_INSIGHT_BOLUS_IDS); - database.execSQL("UPDATE SQLITE_SEQUENCE SET seq = " + System.currentTimeMillis() + " WHERE name = " + DATABASE_INSIGHT_PUMP_IDS); + database.execSQL("INSERT INTO sqlite_sequence (name, seq) SELECT \"" + DATABASE_INSIGHT_BOLUS_IDS + "\", " + System.currentTimeMillis() + " " + + "WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = \"" + DATABASE_INSIGHT_BOLUS_IDS + "\")"); + database.execSQL("INSERT INTO sqlite_sequence (name, seq) SELECT \"" + DATABASE_INSIGHT_PUMP_IDS + "\", " + System.currentTimeMillis() + " " + + "WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = \"" + DATABASE_INSIGHT_PUMP_IDS + "\")"); } catch (SQLException e) { log.error("Can't create database", e); throw new RuntimeException(e); @@ -153,8 +155,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper { TableUtils.createTableIfNotExists(connectionSource, InsightHistoryOffset.class); TableUtils.createTableIfNotExists(connectionSource, InsightBolusID.class); TableUtils.createTableIfNotExists(connectionSource, InsightPumpID.class); - database.execSQL("UPDATE SQLITE_SEQUENCE SET seq = " + System.currentTimeMillis() + " WHERE name = " + DATABASE_INSIGHT_BOLUS_IDS); - database.execSQL("UPDATE SQLITE_SEQUENCE SET seq = " + System.currentTimeMillis() + " WHERE name = " + DATABASE_INSIGHT_PUMP_IDS); + database.execSQL("INSERT INTO sqlite_sequence (name, seq) SELECT \"" + DATABASE_INSIGHT_BOLUS_IDS + "\", " + System.currentTimeMillis() + " " + + "WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = \"" + DATABASE_INSIGHT_BOLUS_IDS + "\")"); + database.execSQL("INSERT INTO sqlite_sequence (name, seq) SELECT \"" + DATABASE_INSIGHT_PUMP_IDS + "\", " + System.currentTimeMillis() + " " + + "WHERE NOT EXISTS (SELECT 1 FROM sqlite_sequence WHERE name = \"" + DATABASE_INSIGHT_PUMP_IDS + "\")"); } else { log.info(DatabaseHelper.class.getName(), "onUpgrade"); TableUtils.dropTable(connectionSource, TempTarget.class, true); From 0eee1c341274e216baac47be71e2af2587a09195 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Wed, 17 Apr 2019 20:31:00 +0200 Subject: [PATCH 14/20] New Crowdin translations (#1745) * New translations strings.xml (Russian) * New translations strings.xml (Russian) --- app/src/main/res/values-ru/strings.xml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index e970c21d48..26d330f64b 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -1,11 +1,11 @@ - Безопасность назначений + Безопасность терапии Макс разрешенный болюс [U] ед. макс разрешенные углеводы (г) опции - синхронисировать назначения с NS + Синхронизировать назначения с NS обнулить базы Вы действительно хотите обнулить базы данных? Выход @@ -116,7 +116,7 @@ профиль NS простой профиль ВремБазал - назначения + Терапия виртуальная помпа Портал лечения / назначений помпа @@ -154,7 +154,7 @@ калькулятор применено ограничение! подтверждение - введите новое назначение + Ввести новое назначение: болюс болюс: базал @@ -690,7 +690,7 @@ Получение времени помпы повторное использование Контроль с часов - Поставить временные цели и ввести назначения с часов. + Ставить временные цели и вводить назначения с часов. Истекло время ожидания соединения Еда грамм @@ -1044,7 +1044,7 @@ Context | Edit Context AndroidAPS перезапущен Найдены сохраненные параметры Внимание: Если вы активируете подключение к невиртуальной помпе, AndroidAPS скопирует настройки базала в профиль помпы, перезаписывая существующие настройки, хранящиеся в ней. Убедитесь, что настройки базала в AndroidAPS корректны. Если вы не уверены или не хотите перезаписать настройки базала на помпу, нажмите отменить и повторите подключение в другое время. - Данные назначений неполные + Данные терапии неполные Параметры обслуживания Адрес электронной почты Недопустимый e-mail From 9be0ffffa9f37274c22833f1c112fb1ffd260277 Mon Sep 17 00:00:00 2001 From: AdrianLxM Date: Wed, 17 Apr 2019 21:28:32 +0200 Subject: [PATCH 15/20] verify static calls on mocked classes --- .../VersionCheckerUtilsKtTest.kt | 45 ++++++++++++++++++- 1 file changed, 43 insertions(+), 2 deletions(-) diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt index b1b62b589d..d711c4f958 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt @@ -63,24 +63,43 @@ class VersionCheckerUtilsKtTest { @PrepareForTest(MainApp::class, L::class, SP::class) fun `should find update1`() { val bus = prepareBus() + compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.2.1") + verify(bus, times(1)).post(any()) + + PowerMockito.verifyStatic(SP::class.java, times(1)) + SP.putLong(eq(R.string.key_new_version_available_since), ArgumentMatchers.anyLong()) + PowerMockito.verifyNoMoreInteractions(SP::class.java) + } @Test @PrepareForTest(MainApp::class, L::class, SP::class) fun `should find update2`() { val bus = prepareBus() + compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.2.1-dev") + verify(bus, times(1)).post(any()) + + PowerMockito.verifyStatic(SP::class.java, times(1)) + SP.putLong(eq(R.string.key_new_version_available_since), ArgumentMatchers.anyLong()) + PowerMockito.verifyNoMoreInteractions(SP::class.java) } @Test @PrepareForTest(MainApp::class, L::class, SP::class) fun `should find update3`() { val bus = prepareBus() + compareWithCurrentVersion(newVersion = "2.2.3", currentVersion = "2.1") + verify(bus, times(1)).post(any()) + + PowerMockito.verifyStatic(SP::class.java, times(1)) + SP.putLong(eq(R.string.key_new_version_available_since), ArgumentMatchers.anyLong()) + PowerMockito.verifyNoMoreInteractions(SP::class.java) } @Test @@ -91,6 +110,10 @@ class VersionCheckerUtilsKtTest { compareWithCurrentVersion(newVersion = "2.2", currentVersion = "2.1.1") verify(bus, times(1)).post(any()) + + PowerMockito.verifyStatic(SP::class.java, times(1)) + SP.putLong(eq(R.string.key_new_version_available_since), ArgumentMatchers.anyLong()) + PowerMockito.verifyNoMoreInteractions(SP::class.java) } @Test @@ -98,16 +121,25 @@ class VersionCheckerUtilsKtTest { fun `should find update5`() { val bus = prepareBus() compareWithCurrentVersion(newVersion = "2.2.1", currentVersion = "2.2-dev") + verify(bus, times(1)).post(any()) + + PowerMockito.verifyStatic(SP::class.java, times(1)) + SP.putLong(eq(R.string.key_new_version_available_since), ArgumentMatchers.anyLong()) + PowerMockito.verifyNoMoreInteractions(SP::class.java) } @Test @PrepareForTest(MainApp::class, L::class, SP::class) fun `should find update6`() { val bus = prepareBus() - val sp = prepareSP() compareWithCurrentVersion(newVersion = "2.2.1", currentVersion = "2.2dev") + verify(bus, times(1)).post(any()) + + PowerMockito.verifyStatic(SP::class.java, times(1)) + SP.putLong(eq(R.string.key_new_version_available_since), ArgumentMatchers.anyLong()) + PowerMockito.verifyNoMoreInteractions(SP::class.java) } @Test @@ -122,8 +154,12 @@ class VersionCheckerUtilsKtTest { """.trimMargin() val bus = prepareBus() compareWithCurrentVersion(buildGradle.byteInputStream().findVersion(), currentVersion = "2.2.2") + verify(bus, times(0)).post(any()) - verify(SP, times(1)).remove(R.string.key_new_version_available_since) + + PowerMockito.verifyStatic(SP::class.java, times(1)) + SP.remove(eq(R.string.key_new_version_available_since)) + PowerMockito.verifyNoMoreInteractions(SP::class.java) } @Test @@ -138,7 +174,12 @@ class VersionCheckerUtilsKtTest { """.trimMargin() val bus = prepareBus() compareWithCurrentVersion(buildGradle.byteInputStream().findVersion(), currentVersion = "2.2.2") + verify(bus, times(1)).post(any()) + + PowerMockito.verifyStatic(SP::class.java, times(1)) + SP.putLong(eq(R.string.key_new_version_available_since), ArgumentMatchers.anyLong()) + PowerMockito.verifyNoMoreInteractions(SP::class.java) } From 84573cc0ccdf6797532d177888f04043d1a70433 Mon Sep 17 00:00:00 2001 From: AdrianLxM Date: Wed, 17 Apr 2019 21:29:16 +0200 Subject: [PATCH 16/20] refactor constraints checker --- .../info/nightscout/androidaps/MainApp.java | 2 +- .../androidaps/data/ConstraintChecker.java | 67 +++++++++---------- .../versionChecker/VersionCheckerPlugin.kt | 21 +++++- .../interfaces/ConstraintsCheckerTest.java | 2 +- 4 files changed, 54 insertions(+), 38 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index 8f626365d9..088f0a4bc3 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -119,7 +119,7 @@ public class MainApp extends Application { log.debug("onCreate"); sInstance = this; sResources = getResources(); - sConstraintsChecker = new ConstraintChecker(this); + sConstraintsChecker = new ConstraintChecker(); sDatabaseHelper = OpenHelperManager.getHelper(sInstance, DatabaseHelper.class); try { diff --git a/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java b/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java index 68664033d0..b1267e81bc 100644 --- a/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java +++ b/app/src/main/java/info/nightscout/androidaps/data/ConstraintChecker.java @@ -1,7 +1,11 @@ package info.nightscout.androidaps.data; +import android.support.annotation.NonNull; + import java.util.ArrayList; +import javax.annotation.Nonnull; + import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.interfaces.Constraint; @@ -15,13 +19,6 @@ import info.nightscout.androidaps.interfaces.PluginType; public class ConstraintChecker implements ConstraintsInterface { - private MainApp mainApp; - - public ConstraintChecker(MainApp mainApp) { - this.mainApp = mainApp; - } - - public Constraint isLoopInvokationAllowed() { return isLoopInvocationAllowed(new Constraint<>(true)); } @@ -79,9 +76,9 @@ public class ConstraintChecker implements ConstraintsInterface { } @Override - public Constraint isLoopInvocationAllowed(Constraint value) { + public Constraint isLoopInvocationAllowed(@NonNull Constraint value) { - ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); for (PluginBase p : constraintsPlugins) { ConstraintsInterface constraint = (ConstraintsInterface) p; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; @@ -91,9 +88,9 @@ public class ConstraintChecker implements ConstraintsInterface { } @Override - public Constraint isClosedLoopAllowed(Constraint value) { + public Constraint isClosedLoopAllowed(@NonNull Constraint value) { - ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); for (PluginBase p : constraintsPlugins) { ConstraintsInterface constraint = (ConstraintsInterface) p; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; @@ -103,9 +100,9 @@ public class ConstraintChecker implements ConstraintsInterface { } @Override - public Constraint isAutosensModeEnabled(Constraint value) { + public Constraint isAutosensModeEnabled(@NonNull Constraint value) { - ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); for (PluginBase p : constraintsPlugins) { ConstraintsInterface constraint = (ConstraintsInterface) p; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; @@ -115,9 +112,9 @@ public class ConstraintChecker implements ConstraintsInterface { } @Override - public Constraint isAMAModeEnabled(Constraint value) { + public Constraint isAMAModeEnabled(@NonNull Constraint value) { - ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); for (PluginBase p : constraintsPlugins) { ConstraintsInterface constrain = (ConstraintsInterface) p; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; @@ -127,9 +124,9 @@ public class ConstraintChecker implements ConstraintsInterface { } @Override - public Constraint isSMBModeEnabled(Constraint value) { + public Constraint isSMBModeEnabled(@NonNull Constraint value) { - ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); for (PluginBase p : constraintsPlugins) { ConstraintsInterface constraint = (ConstraintsInterface) p; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; @@ -139,9 +136,9 @@ public class ConstraintChecker implements ConstraintsInterface { } @Override - public Constraint isUAMEnabled(Constraint value) { + public Constraint isUAMEnabled(@NonNull Constraint value) { - ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); for (PluginBase p : constraintsPlugins) { ConstraintsInterface constraint = (ConstraintsInterface) p; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; @@ -151,8 +148,8 @@ public class ConstraintChecker implements ConstraintsInterface { } @Override - public Constraint isAdvancedFilteringEnabled(Constraint value) { - ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + public Constraint isAdvancedFilteringEnabled(@NonNull Constraint value) { + ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); for (PluginBase p : constraintsPlugins) { ConstraintsInterface constraint = (ConstraintsInterface) p; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; @@ -162,8 +159,8 @@ public class ConstraintChecker implements ConstraintsInterface { } @Override - public Constraint isSuperBolusEnabled(Constraint value) { - ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + public Constraint isSuperBolusEnabled(@NonNull Constraint value) { + ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); for (PluginBase p : constraintsPlugins) { ConstraintsInterface constraint = (ConstraintsInterface) p; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; @@ -173,8 +170,8 @@ public class ConstraintChecker implements ConstraintsInterface { } @Override - public Constraint applyBasalConstraints(Constraint absoluteRate, Profile profile) { - ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + public Constraint applyBasalConstraints(@NonNull Constraint absoluteRate, Profile profile) { + ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); for (PluginBase p : constraintsPlugins) { ConstraintsInterface constraint = (ConstraintsInterface) p; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; @@ -184,8 +181,8 @@ public class ConstraintChecker implements ConstraintsInterface { } @Override - public Constraint applyBasalPercentConstraints(Constraint percentRate, Profile profile) { - ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + public Constraint applyBasalPercentConstraints(@NonNull Constraint percentRate, Profile profile) { + ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); for (PluginBase p : constraintsPlugins) { ConstraintsInterface constrain = (ConstraintsInterface) p; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; @@ -195,8 +192,8 @@ public class ConstraintChecker implements ConstraintsInterface { } @Override - public Constraint applyBolusConstraints(Constraint insulin) { - ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + public Constraint applyBolusConstraints(@NonNull Constraint insulin) { + ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); for (PluginBase p : constraintsPlugins) { ConstraintsInterface constrain = (ConstraintsInterface) p; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; @@ -206,8 +203,8 @@ public class ConstraintChecker implements ConstraintsInterface { } @Override - public Constraint applyExtendedBolusConstraints(Constraint insulin) { - ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + public Constraint applyExtendedBolusConstraints(@NonNull Constraint insulin) { + ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); for (PluginBase p : constraintsPlugins) { ConstraintsInterface constrain = (ConstraintsInterface) p; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; @@ -217,8 +214,8 @@ public class ConstraintChecker implements ConstraintsInterface { } @Override - public Constraint applyCarbsConstraints(Constraint carbs) { - ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + public Constraint applyCarbsConstraints(@NonNull Constraint carbs) { + ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); for (PluginBase p : constraintsPlugins) { ConstraintsInterface constrain = (ConstraintsInterface) p; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; @@ -228,8 +225,8 @@ public class ConstraintChecker implements ConstraintsInterface { } @Override - public Constraint applyMaxIOBConstraints(Constraint maxIob) { - ArrayList constraintsPlugins = mainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); + public Constraint applyMaxIOBConstraints(@NonNull Constraint maxIob) { + ArrayList constraintsPlugins = MainApp.getSpecificPluginsListByInterface(ConstraintsInterface.class); for (PluginBase p : constraintsPlugins) { ConstraintsInterface constrain = (ConstraintsInterface) p; if (!p.isEnabled(PluginType.CONSTRAINTS)) continue; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerPlugin.kt index 99268bcdd9..e3410549ee 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerPlugin.kt @@ -17,6 +17,25 @@ object VersionCheckerPlugin : PluginBase(PluginDescription() .pluginName(R.string.versionChecker)), ConstraintsInterface { override fun isClosedLoopAllowed(value: Constraint): Constraint { - return value + return if (isVeryOldVersion()) + Constraint(false) + else + value } + + override fun applyMaxIOBConstraints(maxIob: Constraint): Constraint { + return if (isOldVersion()) + Constraint(0.toDouble()) + else + maxIob + } + + private fun isOldVersion(): Boolean { + return true + } + + private fun isVeryOldVersion(): Boolean { + return true + } + } diff --git a/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.java b/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.java index ee03ef73d7..fbbd72f064 100644 --- a/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.java +++ b/app/src/test/java/info/nightscout/androidaps/interfaces/ConstraintsCheckerTest.java @@ -289,7 +289,7 @@ public class ConstraintsCheckerTest { //SafetyPlugin when(ConfigBuilderPlugin.getPlugin().getActivePump()).thenReturn(pump); - constraintChecker = new ConstraintChecker(mainApp); + constraintChecker = new ConstraintChecker(); safetyPlugin = SafetyPlugin.getPlugin(); objectivesPlugin = ObjectivesPlugin.getPlugin(); From 4bde759a503c44800ec694095ffaeb5dc0263dd2 Mon Sep 17 00:00:00 2001 From: AdrianLxM Date: Wed, 17 Apr 2019 22:23:35 +0200 Subject: [PATCH 17/20] version checker plugin logic --- .../info/nightscout/androidaps/MainApp.java | 2 + .../overview/notifications/Notification.java | 1 + .../versionChecker/VersionCheckerPlugin.kt | 47 ++++++++++++++----- app/src/main/res/values/strings.xml | 5 ++ 4 files changed, 43 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index 088f0a4bc3..e390d12007 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -50,6 +50,7 @@ import info.nightscout.androidaps.plugins.general.nsclient.receivers.DBAccessRec import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin; import info.nightscout.androidaps.plugins.general.persistentNotification.PersistentNotificationPlugin; import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin; +import info.nightscout.androidaps.plugins.general.versionChecker.VersionCheckerPlugin; import info.nightscout.androidaps.plugins.general.wear.WearPlugin; import info.nightscout.androidaps.plugins.general.xdripStatusline.StatuslinePlugin; import info.nightscout.androidaps.plugins.insulin.InsulinOrefFreePeakPlugin; @@ -179,6 +180,7 @@ public class MainApp extends Application { if (Config.OTHERPROFILES) pluginsList.add(LocalProfilePlugin.getPlugin()); pluginsList.add(TreatmentsPlugin.getPlugin()); if (Config.SAFETY) pluginsList.add(SafetyPlugin.getPlugin()); + if (Config.SAFETY) pluginsList.add(VersionCheckerPlugin.INSTANCE); if (Config.SAFETY) pluginsList.add(StorageConstraintPlugin.getPlugin()); if (Config.APS) pluginsList.add(ObjectivesPlugin.getPlugin()); pluginsList.add(SourceXdripPlugin.getPlugin()); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.java index 3b6bcf615d..f7a4c32360 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/notifications/Notification.java @@ -74,6 +74,7 @@ public class Notification { public static final int DST_LOOP_DISABLED = 49; public static final int DST_IN_24H = 50; public static final int DISKFULL = 51; + public static final int OLDVERSION = 52; public int id; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerPlugin.kt index e3410549ee..d80b3cc7d0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerPlugin.kt @@ -1,7 +1,12 @@ package info.nightscout.androidaps.plugins.general.versionChecker +import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.R import info.nightscout.androidaps.interfaces.* +import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification +import info.nightscout.androidaps.plugins.general.overview.notifications.Notification +import info.nightscout.androidaps.utils.SP +import java.util.concurrent.TimeUnit /** * Usually we would have a class here. @@ -17,25 +22,43 @@ object VersionCheckerPlugin : PluginBase(PluginDescription() .pluginName(R.string.versionChecker)), ConstraintsInterface { override fun isClosedLoopAllowed(value: Constraint): Constraint { - return if (isVeryOldVersion()) - Constraint(false) + checkWarning() + return if (isOldVersion(GRACE_PERIOD_VERY_OLD)) + value.set(false, MainApp.gs(R.string.very_old_version), this) else value } - override fun applyMaxIOBConstraints(maxIob: Constraint): Constraint { - return if (isOldVersion()) - Constraint(0.toDouble()) - else - maxIob + private fun checkWarning() { + val now = System.currentTimeMillis() + if (isOldVersion(GRACE_PERIOD_WARNING) && shouldWarnAgain(now)) { + // store last notification time + SP.putLong(R.string.key_last_versionchecker_waring, now) + + //notify + val message = MainApp.gs(R.string.new_version_warning, Math.round(now / TimeUnit.DAYS.toMillis(1).toDouble())) + val notification = Notification(Notification.OLDVERSION, message, Notification.NORMAL) + MainApp.bus().post(EventNewNotification(notification)) + } } - private fun isOldVersion(): Boolean { - return true + private fun shouldWarnAgain(now: Long) = + now > SP.getLong(R.string.key_last_versionchecker_waring, 0) + WARN_EVERY + + override fun applyMaxIOBConstraints(maxIob: Constraint): Constraint = + if (isOldVersion(GRACE_PERIOD_OLD)) + maxIob.set(0.toDouble(), MainApp.gs(R.string.old_version), this) + else + maxIob + + private fun isOldVersion(gracePeriod: Long): Boolean { + val now = System.currentTimeMillis() + return now > SP.getLong(R.string.key_new_version_available_since, 0) + gracePeriod } - private fun isVeryOldVersion(): Boolean { - return true - } + val WARN_EVERY = TimeUnit.DAYS.toMillis(1) + val GRACE_PERIOD_WARNING = TimeUnit.DAYS.toMillis(30) + val GRACE_PERIOD_OLD = TimeUnit.DAYS.toMillis(60) + val GRACE_PERIOD_VERY_OLD = TimeUnit.DAYS.toMillis(90) } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index feaab74c41..b149bd0f40 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1328,6 +1328,11 @@ Profile switch created Version Checker new_version_available_since + last_versionchecker_waring + old version + very old version + New version for at least %1$d days available! Fallback to LGS after 60 days, loop will be disabled after 90 days + %1$d day %1$d days From 092400f7a01a52847cbf2507ee00188b84de217d Mon Sep 17 00:00:00 2001 From: AdrianLxM Date: Wed, 17 Apr 2019 22:45:21 +0200 Subject: [PATCH 18/20] check regularly --- .../nightscout/androidaps/MainActivity.java | 8 ++++++- .../versionChecker/VersionCheckerPlugin.kt | 21 ++++++++++++++++--- app/src/main/res/values/strings.xml | 4 +++- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/MainActivity.java b/app/src/main/java/info/nightscout/androidaps/MainActivity.java index 7ce5ae2beb..31d462a007 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/MainActivity.java @@ -48,7 +48,9 @@ import info.nightscout.androidaps.events.EventFeatureRunning; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventRefreshGui; import info.nightscout.androidaps.interfaces.PluginBase; +import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus; import info.nightscout.androidaps.plugins.general.versionChecker.VersionCheckerUtilsKt; @@ -115,7 +117,11 @@ public class MainActivity extends AppCompatActivity { public void onPageScrollStateChanged(int state) { } }); - VersionCheckerUtilsKt.checkVersion(); + + //Check here if loop plugin is disabled. Else check via constraints + if (!LoopPlugin.getPlugin().isEnabled(PluginType.LOOP)) + VersionCheckerUtilsKt.checkVersion(); + FabricPrivacy.setUserStats(); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerPlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerPlugin.kt index d80b3cc7d0..7be99e2369 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerPlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerPlugin.kt @@ -23,6 +23,7 @@ object VersionCheckerPlugin : PluginBase(PluginDescription() override fun isClosedLoopAllowed(value: Constraint): Constraint { checkWarning() + checkUpdate() return if (isOldVersion(GRACE_PERIOD_VERY_OLD)) value.set(false, MainApp.gs(R.string.very_old_version), this) else @@ -33,7 +34,7 @@ object VersionCheckerPlugin : PluginBase(PluginDescription() val now = System.currentTimeMillis() if (isOldVersion(GRACE_PERIOD_WARNING) && shouldWarnAgain(now)) { // store last notification time - SP.putLong(R.string.key_last_versionchecker_waring, now) + SP.putLong(R.string.key_last_versionchecker_warning, now) //notify val message = MainApp.gs(R.string.new_version_warning, Math.round(now / TimeUnit.DAYS.toMillis(1).toDouble())) @@ -42,8 +43,21 @@ object VersionCheckerPlugin : PluginBase(PluginDescription() } } + private fun checkUpdate() { + val now = System.currentTimeMillis() + if (shouldCheckVersionAgain(now)) { + // store last notification time + SP.putLong(R.string.key_last_versioncheck, now) + + checkVersion() + } + } + + private fun shouldCheckVersionAgain(now: Long) = + now > SP.getLong(R.string.key_last_versioncheck, 0) + CHECK_EVERY + private fun shouldWarnAgain(now: Long) = - now > SP.getLong(R.string.key_last_versionchecker_waring, 0) + WARN_EVERY + now > SP.getLong(R.string.key_last_versionchecker_warning, 0) + WARN_EVERY override fun applyMaxIOBConstraints(maxIob: Constraint): Constraint = if (isOldVersion(GRACE_PERIOD_OLD)) @@ -53,9 +67,10 @@ object VersionCheckerPlugin : PluginBase(PluginDescription() private fun isOldVersion(gracePeriod: Long): Boolean { val now = System.currentTimeMillis() - return now > SP.getLong(R.string.key_new_version_available_since, 0) + gracePeriod + return now > SP.getLong(R.string.key_new_version_available_since, 0) + gracePeriod } + val CHECK_EVERY = TimeUnit.DAYS.toMillis(1) val WARN_EVERY = TimeUnit.DAYS.toMillis(1) val GRACE_PERIOD_WARNING = TimeUnit.DAYS.toMillis(30) val GRACE_PERIOD_OLD = TimeUnit.DAYS.toMillis(60) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b149bd0f40..9aa326361b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1328,7 +1328,9 @@ Profile switch created Version Checker new_version_available_since - last_versionchecker_waring + last_versionchecker_waring + key_last_versioncheck + old version very old version New version for at least %1$d days available! Fallback to LGS after 60 days, loop will be disabled after 90 days From 6c6b23066bf1fe1ed45bf34d560e6606f7daf9a1 Mon Sep 17 00:00:00 2001 From: AdrianLxM Date: Thu, 18 Apr 2019 00:33:24 +0200 Subject: [PATCH 19/20] mocking the time --- .../versionChecker/VersionCheckerUtilsKtTest.kt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt b/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt index d711c4f958..29725e4d9e 100644 --- a/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt +++ b/app/src/test/java/info/nightscout/androidaps/plugins/general/versionChecker/VersionCheckerUtilsKtTest.kt @@ -14,6 +14,7 @@ import org.powermock.api.mockito.PowerMockito import org.powermock.core.classloader.annotations.PrepareForTest import org.powermock.modules.junit4.PowerMockRunner + @RunWith(PowerMockRunner::class) class VersionCheckerUtilsKtTest { @Test @@ -183,6 +184,15 @@ class VersionCheckerUtilsKtTest { } + @Test + @PrepareForTest(System::class) + fun `set time`() { + PowerMockito.spy(System::class.java) + PowerMockito.`when`(System.currentTimeMillis()).thenReturn(100L) + + assertEquals(100L, System.currentTimeMillis()) + } + private fun prepareBus(): Bus { PowerMockito.mockStatic(MainApp::class.java) val mainApp = mock(MainApp::class.java) @@ -199,8 +209,8 @@ class VersionCheckerUtilsKtTest { } private fun prepareLogging() { - PowerMockito.mockStatic(L::class.java) - `when`(L.isEnabled(any())).thenReturn(true) + PowerMockito.mockStatic(L::class.java) + `when`(L.isEnabled(any())).thenReturn(true) } } \ No newline at end of file From cb5197950e7c32fda4cb12a2d7779101899dfb35 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Thu, 18 Apr 2019 14:05:19 +0200 Subject: [PATCH 20/20] New translations strings.xml (Portuguese) --- app/src/main/res/values-pt/strings.xml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index 6499f63e59..33d67541f7 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -9,6 +9,7 @@ Reinicializar base de dados Quer realmente reiniciar a base de dados? Sair + Usar bólus prolongado de >200%% Dispositivo Bluetooth DanaR Usar sempre valores absolutos de basal Por favor, reinicie o seu telefone ou reinicie o AndroidAPS a partir das Configurações do Sistema \ncaso contrário, o AndroidAPS não terá registro (importante para controlar e verificar se os algoritmos estão a funcionar corretamente)! @@ -313,6 +314,7 @@ Parar STOP PRESSIONADO À espera da bomba + Vão ser administradas %1$.2fU Configuração da visualização e monitoramento, e análise de rácios e basals Verificar se a BG está disponível no Nightscout, e se os dados de insulina da bomba estão a ser carregados A iniciar um open loop @@ -335,11 +337,23 @@ Loop desactivado Loop activado %1$.2f limitado a %2$.2f + O valor %1$s está fora dos limites permitidos O comando remoto não é permitido + O bólus remoto não está disponível. Tente novamente mais tarde. + Para começar a basal %1$.2fU/h durante%2$d min responda com o código %3$s + Para mudar o perfil para %1$s %2$d%% responda com o código %3$s + Para começar o bólus estendido %1$.2fU/h para %2$d min responda com o código %3$s + Para começar a basal %1$d% U/h durante %2$d min responda com o código %3$s Para suspender o loop por %1$d minutos resposta com código %2$s Basal temporária %1$.2fU/h para %2$d min iniciada com êxito + Bólus estendido %1$.2fU/h para %2$d min iniciado com êxito + Basal temporária %1$d% U/h durante%2$d min iniciada com êxito Início basal temp falhou + Falha ao iniciar o bólus estendido + Para parar a basal temporária responda com o código %1$s + Para parar o bólus temporário responda com o código %1$s Basal temp cancelada + Bólus estendido cancelado Não foi possivel cancelar a basal temp Falhou o cancelamento do bolus extendido Comando desconhecido ou resposta errada @@ -450,6 +464,7 @@ Perfil Valor padrão: 3 Por segurança é o valor limite estabelecido por OpenAPS. O que faz é limitar a basal a x3 a basal mázima. Se necessário modificar este valor, por favor ter em conta que os dados apontam para que os limites de segurança sejam - 3 x max diario ou 4x valor actual (qual seja menor) como valores máximos. Valor padrão: 4 Esta é a outra parte dos valores limites de segurança - 3 x max diário ou 4x valor actual - do OpenAPS. Isto define que não importa o valor da basal máxima definido na bomba, o valor máximo da basal temporária não pode ser maior que 4 x o valor da basal definida na bomba. O objectivo é evitar que sejam determinadas basais temporárias demasiado elevadas antes que se perceba como o algoritmo funciona. 4x é um valor que a maior parte das pessoas nunca necessitará de alterar pois o mais provável é necessitar de alterar outras definições para não necessitar de \"ultrapassar\" este limite de segurança. + Valor predefinido: 1.2\n Este é um multiplicador para autosens (e em breve autotune) que coloca um limite máximo de 20%% aos rácios superiores e inferiores de autosens, o que por sua vez calcula o quão alto autosens pode ajustar a basal, quão pode baixar o Factor de Sensibilidade (FSI) e baixar o valor alvo de glicose no sangue. Valor padrão: 0.7\nO outro lado dos limites de segurança do autosens. Coloca um tecto no quão baixo autosens pode ajustar as basais, e quão alto pode ajustar os valores de ISF e valor alvo de glucose no sangue (BG). Autosens também ajusta os alvos Valor padrão: true\nÉ usado para permitir que autosens possa ajustar os valores alvo de glucose no sangue (BG), além de ISF e basais. @@ -462,6 +477,7 @@ Número de telefone não é válido SMS número de telefone inválido Calibração + Enviar calibração %1$.1f para o xDrip? xDrip+ não está instalado Calibração enviada para o xDrip Calibração enviada. Recepção têm de estar activada no xDrip. @@ -602,6 +618,7 @@ Configurações de absorção Tempo máx. absorção refeição [h] Tempo em horas, espectável para que todos os hidratos de carbono da refeição sejam absorvidos + Visualizar bólus prolongado como %% SAGE IAGE CAGE @@ -714,6 +731,8 @@ Enviar dados Glic. para xDrip+ Seleccionar 640g/Eversense como fonte no xDrip+ Glic NSCliente + Valor da basal alterado para o valor mínimo suportado: %1$s + Valor da basal alterado para o valor máximo suportado: %1$s Cálculos Glic Cálculo de Bólus IOB Cálculo de Basal IOB @@ -731,6 +750,8 @@ Modo fechado ativado IOB máxima definida correctamente Glicemia disponivel desde a fonte selecionada + Valores das basais não definidos por horas: %1$s + Perfil inválido: %1$s A programar a bomba para injectar o bolus Actualizar Estado @@ -1072,6 +1093,7 @@ Alterações do modo de funcionamento de registo Alertas de registo Ativar a emulação TBR + Usar bólus prolongados em vez de basais temporárias para contornar o limite de 250%% Atraso de desconexão [s] Número de série Lançar versão de software @@ -1111,11 +1133,13 @@ Basal temporária: %1$d%% para %2$d / %3$d minutos Estendido: %1$.2f / %2$.2f U por %3$d min Multionda: %1$.2f / %2$.2f U por %3$d min + TDD: %1$.2f Reser:%1$.2fU Bat.: %1$d%% Duração máxima da recuperação [s] Duração mínima da recuperação [s] Duração da recuperação + Tempo de operação excedido - reset bluetooth == ∑ %1$s U U/h g/U @@ -1124,6 +1148,8 @@ Criar evento \"Mudança de Sensor\" automaticamente no NS aquando do início do sensor Tomato (MiaoMiao) Tomato + Horário de Verão em 24h ou menos + Horário de Verão a menos de 3 horas - Closed Loop desligado restrição de armazenamento interno Liberte pelo menos %1$d MB do armazenamento interno! Loop desativado! Formato incorrecto