Merge remote-tracking branch 'origin/dagger3' into rs

This commit is contained in:
Milos Kozak 2020-03-30 01:01:24 +02:00
commit 91a8078954
20 changed files with 81 additions and 63 deletions

View file

@ -92,7 +92,6 @@ public class MainActivity extends NoSplashAppCompatActivity {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
AndroidInjection.inject(this);
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
Iconify.with(new FontAwesomeModule()); Iconify.with(new FontAwesomeModule());

View file

@ -10,8 +10,8 @@ import info.nightscout.androidaps.utils.LocaleHelper
open class NoSplashAppCompatActivity : DaggerAppCompatActivity() { open class NoSplashAppCompatActivity : DaggerAppCompatActivity() {
public override fun onCreate(savedInstanceState: Bundle?) { public override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.AppTheme_NoActionBar)
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setTheme(R.style.AppTheme_NoActionBar)
} }
public override fun attachBaseContext(newBase: Context) { public override fun attachBaseContext(newBase: Context) {

View file

@ -2,6 +2,7 @@ package info.nightscout.androidaps.data;
import androidx.collection.LongSparseArray; import androidx.collection.LongSparseArray;
import org.joda.time.DateTime;
import org.json.JSONArray; import org.json.JSONArray;
import org.json.JSONException; import org.json.JSONException;
import org.json.JSONObject; import org.json.JSONObject;
@ -607,13 +608,15 @@ public class Profile {
} }
public static int secondsFromMidnight() { public static int secondsFromMidnight() {
long passed = DateUtil.now() - MidnightTime.calc(); // long passed = DateUtil.now() - MidnightTime.calc();
long passed = new DateTime().getMillisOfDay();
return (int) (passed / 1000); return (int) (passed / 1000);
} }
public static int secondsFromMidnight(long date) { public static int secondsFromMidnight(long date) {
long midnight = MidnightTime.calc(date); //long midnight = MidnightTime.calc(date);
long passed = date - midnight; //long passed = date - midnight;
long passed = new DateTime(date).getMillisOfDay();
return (int) (passed / 1000); return (int) (passed / 1000);
} }

View file

@ -190,6 +190,7 @@ class PluginStore @Inject constructor(
</T> */ </T> */
private fun <T> determineActivePlugin(pluginsInCategory: ArrayList<PluginBase>, private fun <T> determineActivePlugin(pluginsInCategory: ArrayList<PluginBase>,
pluginType: PluginType): T? { pluginType: PluginType): T? {
@Suppress("UNCHECKED_CAST")
val activePlugin = getTheOneEnabledInArray(pluginsInCategory, pluginType) as T? val activePlugin = getTheOneEnabledInArray(pluginsInCategory, pluginType) as T?
if (activePlugin != null) { if (activePlugin != null) {
setFragmentVisiblities((activePlugin as PluginBase).name, pluginsInCategory, pluginType) setFragmentVisiblities((activePlugin as PluginBase).name, pluginsInCategory, pluginType)

View file

@ -57,7 +57,7 @@ class InputTime(injector: HasAndroidInjector) : Element(injector) {
root.addView(l) root.addView(l)
} }
private fun toMills(minutesSinceMidnight: Int): Long = MidnightTime.calc() + T.mins(minutesSinceMidnight.toLong()).msecs() private fun toMills(minutesSinceMidnight: Int): Long = MidnightTime.calcPlusMinutes(minutesSinceMidnight)
private fun getMinSinceMidnight(time: Long): Int = Profile.secondsFromMidnight(time) / 60 private fun getMinSinceMidnight(time: Long): Int = Profile.secondsFromMidnight(time) / 60
} }

View file

@ -80,7 +80,7 @@ class InputTimeRange(injector: HasAndroidInjector) : Element(injector) {
root.addView(l) root.addView(l)
} }
private fun toMills(minutesSinceMidnight: Int): Long = MidnightTime.calc() + T.mins(minutesSinceMidnight.toLong()).msecs() private fun toMills(minutesSinceMidnight: Int): Long = MidnightTime.calcPlusMinutes(minutesSinceMidnight)
private fun getMinSinceMidnight(time: Long): Int = Profile.secondsFromMidnight(time) / 60 private fun getMinSinceMidnight(time: Long): Int = Profile.secondsFromMidnight(time) / 60
} }

View file

@ -93,7 +93,7 @@ class TriggerRecurringTime(injector: HasAndroidInjector) : Trigger(injector) {
override fun duplicate(): Trigger = TriggerRecurringTime(injector, this) override fun duplicate(): Trigger = TriggerRecurringTime(injector, this)
private fun toMills(minutesSinceMidnight: Int): Long = MidnightTime.calc() + T.mins(minutesSinceMidnight.toLong()).msecs() private fun toMills(minutesSinceMidnight: Int): Long = MidnightTime.calcPlusMinutes(minutesSinceMidnight)
private fun getMinSinceMidnight(time: Long): Int = Profile.secondsFromMidnight(time) / 60 private fun getMinSinceMidnight(time: Long): Int = Profile.secondsFromMidnight(time) / 60

View file

@ -76,7 +76,7 @@ class TriggerTimeRange(injector: HasAndroidInjector) : Trigger(injector) {
override fun duplicate(): Trigger = TriggerTimeRange(injector, range.start, range.end) override fun duplicate(): Trigger = TriggerTimeRange(injector, range.start, range.end)
private fun toMills(minutesSinceMidnight: Int): Long = MidnightTime.calc() + T.mins(minutesSinceMidnight.toLong()).msecs() private fun toMills(minutesSinceMidnight: Int): Long = MidnightTime.calcPlusMinutes(minutesSinceMidnight)
private fun getMinSinceMidnight(time: Long): Int = Profile.secondsFromMidnight(time) / 60 private fun getMinSinceMidnight(time: Long): Int = Profile.secondsFromMidnight(time) / 60

View file

@ -703,13 +703,11 @@ class SmsCommunicatorPlugin @Inject constructor(
var grams = SafeParse.stringToInt(splitted[1]) var grams = SafeParse.stringToInt(splitted[1])
var time = DateUtil.now() var time = DateUtil.now()
if (splitted.size > 2) { if (splitted.size > 2) {
val seconds = DateUtil.toSeconds(splitted[2].toUpperCase(Locale.getDefault())) time = DateUtil.toTodayTime(splitted[2].toUpperCase(Locale.getDefault()))
val midnight = MidnightTime.calc() if (time == 0L) {
if (seconds == 0 && (!splitted[2].startsWith("00:00") || !splitted[2].startsWith("12:00"))) {
sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat))) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))
return return
} }
time = midnight + T.secs(seconds.toLong()).msecs() // TODO: this is wrong during leap day
} }
grams = constraintChecker.applyCarbsConstraints(Constraint(grams)).value() grams = constraintChecker.applyCarbsConstraints(Constraint(grams)).value()
if (grams == 0) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat))) if (grams == 0) sendSMS(Sms(receivedSms.phoneNumber, resourceHelper.gs(R.string.wrongformat)))

View file

@ -50,7 +50,8 @@ class TidepoolPlugin @Inject constructor(
private val fabricPrivacy: FabricPrivacy, private val fabricPrivacy: FabricPrivacy,
private val tidepoolUploader: TidepoolUploader, private val tidepoolUploader: TidepoolUploader,
private val uploadChunk: UploadChunk, private val uploadChunk: UploadChunk,
private val sp: SP private val sp: SP,
private val rateLimit: RateLimit
) : PluginBase(PluginDescription() ) : PluginBase(PluginDescription()
.mainType(PluginType.GENERAL) .mainType(PluginType.GENERAL)
.pluginName(R.string.tidepool) .pluginName(R.string.tidepool)
@ -103,7 +104,7 @@ class TidepoolPlugin @Inject constructor(
if (isEnabled(PluginType.GENERAL) if (isEnabled(PluginType.GENERAL)
&& (!sp.getBoolean(R.string.key_tidepool_only_while_charging, false) || ChargingStateReceiver.isCharging()) && (!sp.getBoolean(R.string.key_tidepool_only_while_charging, false) || ChargingStateReceiver.isCharging())
&& (!sp.getBoolean(R.string.key_tidepool_only_while_unmetered, false) || NetworkChangeReceiver.isWifiConnected()) && (!sp.getBoolean(R.string.key_tidepool_only_while_unmetered, false) || NetworkChangeReceiver.isWifiConnected())
&& RateLimit.rateLimit("tidepool-new-data-upload", T.mins(4).secs().toInt())) && rateLimit.rateLimit("tidepool-new-data-upload", T.mins(4).secs().toInt()))
doUpload() doUpload()
}, { }, {
fabricPrivacy.logException(it) fabricPrivacy.logException(it)

View file

@ -1,32 +1,22 @@
package info.nightscout.androidaps.plugins.general.tidepool.comm package info.nightscout.androidaps.plugins.general.tidepool.comm
import info.nightscout.androidaps.logging.L import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper import info.nightscout.androidaps.logging.LTag
import okhttp3.Interceptor import okhttp3.Interceptor
import okhttp3.Response import okhttp3.Response
import okio.Buffer import okio.Buffer
import org.slf4j.LoggerFactory
import java.io.IOException import java.io.IOException
class InfoInterceptor(tag: String) : Interceptor { class InfoInterceptor(val tag: String = "interceptor", val aapsLogger: AAPSLogger) : Interceptor {
private val log = StacktraceLoggerWrapper.getLogger(L.TIDEPOOL)
private var tag = "interceptor"
init {
this.tag = tag
}
@Throws(IOException::class) @Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response { override fun intercept(chain: Interceptor.Chain): Response {
val request = chain.request() val request = chain.request()
request.body?.let { request.body?.let {
if (L.isEnabled(L.TIDEPOOL)) { aapsLogger.debug(LTag.TIDEPOOL, "Interceptor Body size: " + it.contentLength())
log.debug("Interceptor Body size: " + it.contentLength()) val requestBuffer = Buffer()
val requestBuffer = Buffer() it.writeTo(requestBuffer)
it.writeTo(requestBuffer) aapsLogger.debug(LTag.TIDEPOOL, "Interceptor Body: " + requestBuffer.readUtf8())
log.debug("Interceptor Body: " + requestBuffer.readUtf8())
}
} }
return chain.proceed(request) return chain.proceed(request)
} }

View file

@ -68,7 +68,7 @@ class TidepoolUploader @Inject constructor(
val client = OkHttpClient.Builder() val client = OkHttpClient.Builder()
.addInterceptor(httpLoggingInterceptor) .addInterceptor(httpLoggingInterceptor)
.addInterceptor(InfoInterceptor(TidepoolUploader::class.java.name)) .addInterceptor(InfoInterceptor(TidepoolUploader::class.java.name, aapsLogger))
.build() .build()
retrofit = Retrofit.Builder() retrofit = Retrofit.Builder()

View file

@ -1,23 +1,13 @@
package info.nightscout.androidaps.plugins.general.tidepool.events package info.nightscout.androidaps.plugins.general.tidepool.events
import info.nightscout.androidaps.events.Event import info.nightscout.androidaps.events.Event
import info.nightscout.androidaps.logging.L
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import org.slf4j.LoggerFactory
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
class EventTidepoolStatus(val status: String) : Event() { class EventTidepoolStatus(val status: String) : Event() {
private val log = StacktraceLoggerWrapper.getLogger(L.TIDEPOOL)
var date: Long = DateUtil.now() var date: Long = DateUtil.now()
init {
if (L.isEnabled(L.TIDEPOOL))
log.debug("New status: $status")
}
private var timeFormat = SimpleDateFormat("HH:mm:ss", Locale.getDefault()) private var timeFormat = SimpleDateFormat("HH:mm:ss", Locale.getDefault())
fun toPreparedHtml(): StringBuilder { fun toPreparedHtml(): StringBuilder {
@ -29,5 +19,4 @@ class EventTidepoolStatus(val status: String) : Event() {
stringBuilder.append("<br>") stringBuilder.append("<br>")
return stringBuilder return stringBuilder
} }
} }

View file

@ -1,26 +1,27 @@
package info.nightscout.androidaps.plugins.general.tidepool.utils package info.nightscout.androidaps.plugins.general.tidepool.utils
import info.nightscout.androidaps.logging.L import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.StacktraceLoggerWrapper import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.T
import org.slf4j.LoggerFactory
import java.util.* import java.util.*
import javax.inject.Inject
import javax.inject.Singleton
object RateLimit { @Singleton
class RateLimit @Inject constructor(
val aapsLogger: AAPSLogger
) {
private val rateLimits = HashMap<String, Long>() private val rateLimits = HashMap<String, Long>()
private val log = StacktraceLoggerWrapper.getLogger(L.TIDEPOOL)
// return true if below rate limit // return true if below rate limit
@Synchronized @Synchronized
fun rateLimit(name: String, seconds: Int): Boolean { fun rateLimit(name: String, seconds: Int): Boolean {
// check if over limit // check if over limit
rateLimits[name]?.let { rateLimits[name]?.let {
if (DateUtil.now() - it < T.secs(seconds.toLong()).msecs()) { if (DateUtil.now() - it < T.secs(seconds.toLong()).msecs()) {
if (L.isEnabled(L.TIDEPOOL)) aapsLogger.debug(LTag.TIDEPOOL, "$name rate limited: $seconds seconds")
log.debug("$name rate limited: $seconds seconds")
return false return false
} }
} }

View file

@ -108,6 +108,28 @@ public class DateUtil {
return retval; return retval;
} }
public static long toTodayTime(String hh_colon_mm) {
Pattern p = Pattern.compile("(\\d+):(\\d+)( a.m.| p.m.| AM| PM|AM|PM|)");
Matcher m = p.matcher(hh_colon_mm);
long retval = 0;
if (m.find()) {
int hours = SafeParse.stringToInt(m.group(1));
int minutes = SafeParse.stringToInt(m.group(2));
if ((m.group(3).equals(" a.m.") || m.group(3).equals(" AM") || m.group(3).equals("AM")) && m.group(1).equals("12"))
hours -= 12;
if ((m.group(3).equals(" p.m.") || m.group(3).equals(" PM") || m.group(3).equals("PM")) && !(m.group(1).equals("12")))
hours += 12;
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, hours);
c.set(Calendar.MINUTE, minutes);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
retval = c.getTimeInMillis();
}
return retval;
}
public static String dateString(Date date) { public static String dateString(Date date) {
DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT); DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
return df.format(date); return df.format(date);

View file

@ -4,16 +4,19 @@ import android.content.Context
import android.content.ContextWrapper import android.content.ContextWrapper
import android.os.Build import android.os.Build
import android.os.LocaleList import android.os.LocaleList
import androidx.preference.PreferenceManager
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import java.util.* import java.util.*
object LocaleHelper { object LocaleHelper {
fun currentLanguage(): String = private fun currentLanguage(context: Context): String =
SP.getString(R.string.key_language, Locale.getDefault().language) PreferenceManager.getDefaultSharedPreferences(context).getString(context.getString(R.string.key_language), "en")
?: "en"
// injection not possible because of use in attachBaseContext
//SP.getString(R.string.key_language, Locale.getDefault().language)
private fun currentLocale(): Locale { private fun currentLocale(context: Context): Locale {
val language = currentLanguage() val language = currentLanguage(context)
var locale = Locale(language) var locale = Locale(language)
if (language.contains("_")) { if (language.contains("_")) {
// language with country like pt_BR defined in arrays.xml // language with country like pt_BR defined in arrays.xml
@ -26,7 +29,7 @@ object LocaleHelper {
@Suppress("DEPRECATION") @Suppress("DEPRECATION")
fun update(context: Context) { fun update(context: Context) {
val locale = currentLocale() val locale = currentLocale(context)
Locale.setDefault(locale) Locale.setDefault(locale)
val resources = context.resources val resources = context.resources
val configuration = resources.configuration val configuration = resources.configuration
@ -39,7 +42,7 @@ object LocaleHelper {
fun wrap(ctx: Context): ContextWrapper { fun wrap(ctx: Context): ContextWrapper {
val res = ctx.resources val res = ctx.resources
val configuration = res.configuration val configuration = res.configuration
val newLocale = currentLocale() val newLocale = currentLocale(ctx)
val context = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { val context = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
configuration.setLocale(newLocale) configuration.setLocale(newLocale)
val localeList = LocaleList(newLocale) val localeList = LocaleList(newLocale)

View file

@ -21,6 +21,17 @@ public class MidnightTime {
return c.getTimeInMillis(); return c.getTimeInMillis();
} }
public static long calcPlusMinutes(int minutes) {
int h = minutes / 60;
int m = minutes % 60;
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, h);
c.set(Calendar.MINUTE, m);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
return c.getTimeInMillis();
}
public static long calc(long time) { public static long calc(long time) {
Long m; Long m;
synchronized (times) { synchronized (times) {

View file

@ -40,7 +40,7 @@ class TddCalculator @Inject constructor(
fun calculate(days: Long): LongSparseArray<TDD> { fun calculate(days: Long): LongSparseArray<TDD> {
val range = T.days(days + 1).msecs() val range = T.days(days + 1).msecs()
val startTime = MidnightTime.calc(DateUtil.now()) - T.days(days).msecs() val startTime = MidnightTime.calc(DateUtil.now() - T.days(days).msecs())
val endTime = MidnightTime.calc(DateUtil.now()) val endTime = MidnightTime.calc(DateUtil.now())
initializeData(range) initializeData(range)

View file

@ -23,7 +23,7 @@ class TirCalculator @Inject constructor(
fun calculate(days: Long, lowMgdl: Double, highMgdl: Double): LongSparseArray<TIR> { fun calculate(days: Long, lowMgdl: Double, highMgdl: Double): LongSparseArray<TIR> {
if (lowMgdl < 39) throw RuntimeException("Low below 39") if (lowMgdl < 39) throw RuntimeException("Low below 39")
if (lowMgdl > highMgdl) throw RuntimeException("Low > High") if (lowMgdl > highMgdl) throw RuntimeException("Low > High")
val startTime = MidnightTime.calc(DateUtil.now()) - T.days(days).msecs() val startTime = MidnightTime.calc(DateUtil.now() - T.days(days).msecs())
val endTime = MidnightTime.calc(DateUtil.now()) val endTime = MidnightTime.calc(DateUtil.now())
val bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime(startTime, endTime, true) val bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime(startTime, endTime, true)

View file

@ -22,9 +22,9 @@ class TriggerTimeRangeTest : TriggerTestBase() {
@Before @Before
fun mock() { fun mock() {
var realNow = System.currentTimeMillis()
PowerMockito.mockStatic(DateUtil::class.java) PowerMockito.mockStatic(DateUtil::class.java)
PowerMockito.`when`(DateUtil.now()).thenReturn(now.toLong() * 60000 + MidnightTime.calc(realNow)) val nowMills = MidnightTime.calcPlusMinutes(now)
PowerMockito.`when`(DateUtil.now()).thenReturn(nowMills)
} }
@Test @Test