utils -> kt
This commit is contained in:
parent
37cee04926
commit
3c292e711f
10 changed files with 231 additions and 279 deletions
|
@ -1,14 +0,0 @@
|
||||||
package info.nightscout.androidaps.interaction.utils;
|
|
||||||
|
|
||||||
public class Constants {
|
|
||||||
|
|
||||||
public static final long SECOND_IN_MS = 1000;
|
|
||||||
public static final long MINUTE_IN_MS = 60000;
|
|
||||||
public static final long HOUR_IN_MS = 3600000;
|
|
||||||
public static final long DAY_IN_MS = 86400000;
|
|
||||||
public static final long WEEK_IN_MS = DAY_IN_MS * 7;
|
|
||||||
public static final long MONTH_IN_MS = DAY_IN_MS * 30;
|
|
||||||
|
|
||||||
public static final long STALE_MS = Constants.MINUTE_IN_MS * 12;
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
package info.nightscout.androidaps.interaction.utils
|
||||||
|
|
||||||
|
@Suppress("unused")
|
||||||
|
object Constants {
|
||||||
|
|
||||||
|
const val SECOND_IN_MS: Long = 1000
|
||||||
|
const val MINUTE_IN_MS: Long = 60000
|
||||||
|
const val HOUR_IN_MS: Long = 3600000
|
||||||
|
const val DAY_IN_MS: Long = 86400000
|
||||||
|
const val WEEK_IN_MS = DAY_IN_MS * 7
|
||||||
|
const val MONTH_IN_MS = DAY_IN_MS * 30
|
||||||
|
const val STALE_MS = MINUTE_IN_MS * 12
|
||||||
|
}
|
|
@ -12,7 +12,8 @@ public class DisplayFormat {
|
||||||
@Inject SP sp;
|
@Inject SP sp;
|
||||||
@Inject WearUtil wearUtil;
|
@Inject WearUtil wearUtil;
|
||||||
|
|
||||||
@Inject DisplayFormat() {}
|
@Inject DisplayFormat() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximal and minimal lengths of fields/labels shown in complications, in characters
|
* Maximal and minimal lengths of fields/labels shown in complications, in characters
|
||||||
|
@ -74,12 +75,12 @@ public class DisplayFormat {
|
||||||
}
|
}
|
||||||
|
|
||||||
// that only optimizes obvious things like 0 before . or at end, + at beginning
|
// that only optimizes obvious things like 0 before . or at end, + at beginning
|
||||||
String delta = (new SmallestDoubleString(raw.getSingleBg().getDelta())).minimise(MAX_FIELD_LEN_SHORT -1);
|
String delta = (new SmallestDoubleString(raw.getSingleBg().getDelta())).minimise(MAX_FIELD_LEN_SHORT - 1);
|
||||||
if (minutes.length() + delta.length() + deltaSymbol().length() + 1 <= MAX_FIELD_LEN_SHORT) {
|
if (minutes.length() + delta.length() + deltaSymbol().length() + 1 <= MAX_FIELD_LEN_SHORT) {
|
||||||
return minutes + " " + deltaSymbol() + delta;
|
return minutes + " " + deltaSymbol() + delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
String shortDelta = (new SmallestDoubleString(raw.getSingleBg().getDelta())).minimise(MAX_FIELD_LEN_SHORT -(1+minutes.length()));
|
String shortDelta = (new SmallestDoubleString(raw.getSingleBg().getDelta())).minimise(MAX_FIELD_LEN_SHORT - (1 + minutes.length()));
|
||||||
|
|
||||||
return minutes + " " + shortDelta;
|
return minutes + " " + shortDelta;
|
||||||
}
|
}
|
||||||
|
@ -96,7 +97,7 @@ public class DisplayFormat {
|
||||||
final String SEP_MIN = " ";
|
final String SEP_MIN = " ";
|
||||||
|
|
||||||
String line =
|
String line =
|
||||||
raw.getStatus().getCob() + SEP_LONG + raw.getStatus().getIobSum() + SEP_LONG + basalRateSymbol()+raw.getStatus().getCurrentBasal();
|
raw.getStatus().getCob() + SEP_LONG + raw.getStatus().getIobSum() + SEP_LONG + basalRateSymbol() + raw.getStatus().getCurrentBasal();
|
||||||
if (line.length() <= MAX_FIELD_LEN_LONG) {
|
if (line.length() <= MAX_FIELD_LEN_LONG) {
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
@ -105,14 +106,14 @@ public class DisplayFormat {
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
int remainingMax = MAX_FIELD_LEN_LONG - (raw.getStatus().getCob().length() + raw.getStatus().getCurrentBasal().length() + SEP_SHORT_LEN*2);
|
int remainingMax = MAX_FIELD_LEN_LONG - (raw.getStatus().getCob().length() + raw.getStatus().getCurrentBasal().length() + SEP_SHORT_LEN * 2);
|
||||||
final String smallestIoB = new SmallestDoubleString(raw.getStatus().getIobSum(), SmallestDoubleString.Units.USE).minimise(Math.max(MIN_FIELD_LEN_IOB, remainingMax));
|
final String smallestIoB = new SmallestDoubleString(raw.getStatus().getIobSum(), SmallestDoubleString.Units.USE).minimise(Math.max(MIN_FIELD_LEN_IOB, remainingMax));
|
||||||
line = raw.getStatus().getCob() + SEP_SHORT + smallestIoB + SEP_SHORT + raw.getStatus().getCurrentBasal();
|
line = raw.getStatus().getCob() + SEP_SHORT + smallestIoB + SEP_SHORT + raw.getStatus().getCurrentBasal();
|
||||||
if (line.length() <= MAX_FIELD_LEN_LONG) {
|
if (line.length() <= MAX_FIELD_LEN_LONG) {
|
||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
remainingMax = MAX_FIELD_LEN_LONG - (smallestIoB.length() + raw.getStatus().getCurrentBasal().length() + SEP_SHORT_LEN*2);
|
remainingMax = MAX_FIELD_LEN_LONG - (smallestIoB.length() + raw.getStatus().getCurrentBasal().length() + SEP_SHORT_LEN * 2);
|
||||||
final String simplifiedCob = new SmallestDoubleString(raw.getStatus().getCob(), SmallestDoubleString.Units.USE).minimise(Math.max(MIN_FIELD_LEN_COB, remainingMax));
|
final String simplifiedCob = new SmallestDoubleString(raw.getStatus().getCob(), SmallestDoubleString.Units.USE).minimise(Math.max(MIN_FIELD_LEN_COB, remainingMax));
|
||||||
|
|
||||||
line = simplifiedCob + SEP_SHORT + smallestIoB + SEP_SHORT + raw.getStatus().getCurrentBasal();
|
line = simplifiedCob + SEP_SHORT + smallestIoB + SEP_SHORT + raw.getStatus().getCurrentBasal();
|
||||||
|
@ -135,13 +136,13 @@ public class DisplayFormat {
|
||||||
if (iobBolus.trim().length() == 0) {
|
if (iobBolus.trim().length() == 0) {
|
||||||
iobBolus = "--";
|
iobBolus = "--";
|
||||||
}
|
}
|
||||||
String iobBasal = new SmallestDoubleString(iobs[1]).minimise((MAX_FIELD_LEN_SHORT -1) - Math.max(MIN_FIELD_LEN_IOB, iobBolus.length()));
|
String iobBasal = new SmallestDoubleString(iobs[1]).minimise((MAX_FIELD_LEN_SHORT - 1) - Math.max(MIN_FIELD_LEN_IOB, iobBolus.length()));
|
||||||
if (iobBasal.trim().length() == 0) {
|
if (iobBasal.trim().length() == 0) {
|
||||||
iobBasal = "--";
|
iobBasal = "--";
|
||||||
}
|
}
|
||||||
iob2 = iobBolus+" "+iobBasal;
|
iob2 = iobBolus + " " + iobBasal;
|
||||||
}
|
}
|
||||||
return Pair.create(iob1, iob2);
|
return new Pair(iob1, iob2);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<String, String> detailedCob(final RawDisplayData raw) {
|
public Pair<String, String> detailedCob(final RawDisplayData raw) {
|
||||||
|
@ -152,6 +153,6 @@ public class DisplayFormat {
|
||||||
cob2 = cobMini.getExtra() + cobMini.getUnits();
|
cob2 = cobMini.getExtra() + cobMini.getUnits();
|
||||||
}
|
}
|
||||||
final String cob1 = cobMini.minimise(MAX_FIELD_LEN_SHORT);
|
final String cob1 = cobMini.minimise(MAX_FIELD_LEN_SHORT);
|
||||||
return Pair.create(cob1, cob2);
|
return new Pair(cob1, cob2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,115 +0,0 @@
|
||||||
package info.nightscout.androidaps.interaction.utils;
|
|
||||||
|
|
||||||
import android.os.PowerManager;
|
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.BuildConfig;
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
|
||||||
import info.nightscout.shared.logging.AAPSLogger;
|
|
||||||
import info.nightscout.shared.logging.LTag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created for xDrip by jamorham on 07/03/2018
|
|
||||||
* Adapted for AAPS by dlvoy on 2019-11-11
|
|
||||||
*
|
|
||||||
* Tasks which are fired from events can be scheduled here and only execute when they become idle
|
|
||||||
* and are not being rescheduled within their wait window.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
public class Inevitable {
|
|
||||||
|
|
||||||
@Inject WearUtil wearUtil;
|
|
||||||
@Inject AAPSLogger aapsLogger;
|
|
||||||
@Inject DateUtil dateUtil;
|
|
||||||
|
|
||||||
@Inject Inevitable() {}
|
|
||||||
|
|
||||||
private static final int MAX_QUEUE_TIME = (int) Constants.MINUTE_IN_MS * 6;
|
|
||||||
private static final boolean debug = BuildConfig.DEBUG;
|
|
||||||
|
|
||||||
private final ConcurrentHashMap<String, Task> tasks = new ConcurrentHashMap<>();
|
|
||||||
|
|
||||||
public void task(final String id, long idle_for, Runnable runnable) {
|
|
||||||
if (idle_for > MAX_QUEUE_TIME) {
|
|
||||||
throw new RuntimeException(id + " Requested time: " + idle_for + " beyond max queue time");
|
|
||||||
}
|
|
||||||
final Task task = tasks.get(id);
|
|
||||||
if (task != null) {
|
|
||||||
// if it already exists then extend the time
|
|
||||||
task.extendTime(idle_for);
|
|
||||||
|
|
||||||
if (debug)
|
|
||||||
aapsLogger.debug(LTag.WEAR, "Extending time for: " + id + " to " + dateUtil.dateAndTimeAndSecondsString(task.when));
|
|
||||||
} else {
|
|
||||||
// otherwise create new task
|
|
||||||
if (runnable == null) return; // extension only if already exists
|
|
||||||
tasks.put(id, new Task(id, idle_for, runnable));
|
|
||||||
|
|
||||||
if (debug) {
|
|
||||||
aapsLogger.debug(LTag.WEAR,
|
|
||||||
"Creating task: " + id + " due: " + dateUtil.dateAndTimeAndSecondsString(tasks.get(id).when));
|
|
||||||
}
|
|
||||||
|
|
||||||
// create a thread to wait and execute in background
|
|
||||||
final Thread t = new Thread(() -> {
|
|
||||||
final PowerManager.WakeLock wl = wearUtil.getWakeLock(id, MAX_QUEUE_TIME + 5000);
|
|
||||||
try {
|
|
||||||
boolean running = true;
|
|
||||||
// wait for task to be due or killed
|
|
||||||
while (running) {
|
|
||||||
wearUtil.threadSleep(500);
|
|
||||||
final Task thisTask = tasks.get(id);
|
|
||||||
running = thisTask != null && !thisTask.poll();
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
wearUtil.releaseWakeLock(wl);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
t.setPriority(Thread.MIN_PRIORITY);
|
|
||||||
t.start();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void kill(final String id) {
|
|
||||||
tasks.remove(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Task {
|
|
||||||
private long when;
|
|
||||||
private final Runnable what;
|
|
||||||
private final String id;
|
|
||||||
|
|
||||||
Task(String id, long offset, Runnable what) {
|
|
||||||
this.what = what;
|
|
||||||
this.id = id;
|
|
||||||
extendTime(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void extendTime(long offset) {
|
|
||||||
this.when = wearUtil.timestamp() + offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean poll() {
|
|
||||||
final long till = wearUtil.msTill(when);
|
|
||||||
if (till < 1) {
|
|
||||||
if (debug) aapsLogger.debug(LTag.WEAR, "Executing task! " + this.id);
|
|
||||||
tasks.remove(this.id); // early remove to allow overlapping scheduling
|
|
||||||
what.run();
|
|
||||||
return true;
|
|
||||||
} else if (till > MAX_QUEUE_TIME) {
|
|
||||||
aapsLogger.debug(LTag.WEAR, "Task: " + this.id + " In queue too long: " + till);
|
|
||||||
tasks.remove(this.id);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
package info.nightscout.androidaps.interaction.utils
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.BuildConfig
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil
|
||||||
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
|
import info.nightscout.shared.logging.LTag
|
||||||
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created for xDrip by jamorham on 07/03/2018
|
||||||
|
* Adapted for AAPS by dlvoy on 2019-11-11
|
||||||
|
*
|
||||||
|
* Tasks which are fired from events can be scheduled here and only execute when they become idle
|
||||||
|
* and are not being rescheduled within their wait window.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
class Inevitable @Inject internal constructor() {
|
||||||
|
|
||||||
|
@Inject lateinit var wearUtil: WearUtil
|
||||||
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
|
@Inject lateinit var dateUtil: DateUtil
|
||||||
|
|
||||||
|
private val tasks = ConcurrentHashMap<String, Task>()
|
||||||
|
fun task(id: String, idle_for: Long, runnable: Runnable?) {
|
||||||
|
if (idle_for > MAX_QUEUE_TIME) {
|
||||||
|
throw RuntimeException("$id Requested time: $idle_for beyond max queue time")
|
||||||
|
}
|
||||||
|
val task = tasks[id]
|
||||||
|
if (task != null) {
|
||||||
|
// if it already exists then extend the time
|
||||||
|
task.extendTime(idle_for)
|
||||||
|
if (debug) aapsLogger.debug(LTag.WEAR, "Extending time for: " + id + " to " + dateUtil.dateAndTimeAndSecondsString(task.`when`))
|
||||||
|
} else {
|
||||||
|
// otherwise create new task
|
||||||
|
if (runnable == null) return // extension only if already exists
|
||||||
|
tasks[id] = Task(id, idle_for, runnable)
|
||||||
|
if (debug) {
|
||||||
|
aapsLogger.debug(
|
||||||
|
LTag.WEAR,
|
||||||
|
"Creating task: " + id + " due: " + dateUtil.dateAndTimeAndSecondsString(tasks[id]!!.`when`)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// create a thread to wait and execute in background
|
||||||
|
val t = Thread {
|
||||||
|
val wl = wearUtil.getWakeLock(id, MAX_QUEUE_TIME + 5000)
|
||||||
|
try {
|
||||||
|
var running = true
|
||||||
|
// wait for task to be due or killed
|
||||||
|
while (running) {
|
||||||
|
wearUtil.threadSleep(500)
|
||||||
|
val thisTask = tasks[id]
|
||||||
|
running = thisTask != null && !thisTask.poll()
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
wearUtil.releaseWakeLock(wl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
t.priority = Thread.MIN_PRIORITY
|
||||||
|
t.start()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun kill(id: String) {
|
||||||
|
tasks.remove(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
private inner class Task(private val id: String, offset: Long, private val what: Runnable) {
|
||||||
|
|
||||||
|
var `when`: Long = 0
|
||||||
|
fun extendTime(offset: Long) {
|
||||||
|
`when` = wearUtil.timestamp() + offset
|
||||||
|
}
|
||||||
|
|
||||||
|
fun poll(): Boolean {
|
||||||
|
val till = wearUtil.msTill(`when`)
|
||||||
|
if (till < 1) {
|
||||||
|
if (debug) aapsLogger.debug(LTag.WEAR, "Executing task! $id")
|
||||||
|
tasks.remove(id) // early remove to allow overlapping scheduling
|
||||||
|
what.run()
|
||||||
|
return true
|
||||||
|
} else if (till > MAX_QUEUE_TIME) {
|
||||||
|
aapsLogger.debug(LTag.WEAR, "Task: $id In queue too long: $till")
|
||||||
|
tasks.remove(id)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
init {
|
||||||
|
extendTime(offset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
private const val MAX_QUEUE_TIME = Constants.MINUTE_IN_MS.toInt() * 6
|
||||||
|
private val debug = BuildConfig.DEBUG
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,43 +0,0 @@
|
||||||
package info.nightscout.androidaps.interaction.utils;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Same as android Pair, but clean room java class - does not require Android SDK for tests
|
|
||||||
*/
|
|
||||||
public class Pair<F, S> {
|
|
||||||
|
|
||||||
public final F first;
|
|
||||||
public final S second;
|
|
||||||
|
|
||||||
public Pair(F first, S second) {
|
|
||||||
this.first = first;
|
|
||||||
this.second = second;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <F, S> Pair<F, S> create(F f, S s) {
|
|
||||||
return new Pair<>(f, s);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(java.lang.Object o) {
|
|
||||||
if (o instanceof Pair) {
|
|
||||||
return ((Pair) o).first.equals(first) && ((Pair) o).second.equals(second);
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "First: \""+first.toString()+"\" Second: \""+second.toString()+"\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Objects.hash(first, second);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
package info.nightscout.androidaps.interaction.utils
|
||||||
|
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Same as android Pair, but clean room java class - does not require Android SDK for tests
|
||||||
|
*/
|
||||||
|
class Pair<F, S>(val first: F, val second: S) {
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean =
|
||||||
|
if (other is Pair<*, *>) other.first == first && other.second == second
|
||||||
|
else false
|
||||||
|
|
||||||
|
override fun toString(): String = "First: \"" + first.toString() + "\" Second: \"" + second.toString() + "\""
|
||||||
|
override fun hashCode(): Int = Objects.hash(first, second)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
fun <F, S> create(f: F, s: S): Pair<F, S> = Pair(f, s)
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,96 +0,0 @@
|
||||||
package info.nightscout.androidaps.interaction.utils;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.os.PowerManager;
|
|
||||||
|
|
||||||
import com.google.android.gms.wearable.DataMap;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
|
|
||||||
import info.nightscout.shared.logging.AAPSLogger;
|
|
||||||
import info.nightscout.shared.logging.LTag;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by andy on 3/5/19.
|
|
||||||
* Adapted by dlvoy on 2019-11-06 using code from jamorham JoH class
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
public class WearUtil {
|
|
||||||
|
|
||||||
@Inject public Context context;
|
|
||||||
@Inject public AAPSLogger aapsLogger;
|
|
||||||
|
|
||||||
@Inject public WearUtil() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private final boolean debug_wakelocks = false;
|
|
||||||
private final Map<String, Long> rateLimits = new HashMap<>();
|
|
||||||
|
|
||||||
//==============================================================================================
|
|
||||||
// Time related util methods
|
|
||||||
//==============================================================================================
|
|
||||||
|
|
||||||
public long timestamp() {
|
|
||||||
return System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
public long msSince(long when) {
|
|
||||||
return (timestamp() - when);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long msTill(long when) {
|
|
||||||
return (when - timestamp());
|
|
||||||
}
|
|
||||||
|
|
||||||
//==============================================================================================
|
|
||||||
// Thread and power management utils
|
|
||||||
//==============================================================================================
|
|
||||||
|
|
||||||
// return true if below rate limit
|
|
||||||
public synchronized boolean isBelowRateLimit(String named, int onceForSeconds) {
|
|
||||||
// check if over limit
|
|
||||||
if ((rateLimits.containsKey(named)) && (timestamp() - rateLimits.get(named) < (onceForSeconds * 1000))) {
|
|
||||||
aapsLogger.debug(LTag.WEAR, named + " rate limited to one for " + onceForSeconds + " seconds");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// not over limit
|
|
||||||
rateLimits.put(named, timestamp());
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public PowerManager.WakeLock getWakeLock(final String name, int millis) {
|
|
||||||
final PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
|
|
||||||
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AAPS::" + name);
|
|
||||||
wl.acquire(millis);
|
|
||||||
if (debug_wakelocks)
|
|
||||||
aapsLogger.debug(LTag.WEAR, "getWakeLock: " + name + " " + wl);
|
|
||||||
return wl;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void releaseWakeLock(PowerManager.WakeLock wl) {
|
|
||||||
if (debug_wakelocks) aapsLogger.debug(LTag.WEAR, "releaseWakeLock: " + wl.toString());
|
|
||||||
if (wl == null) return;
|
|
||||||
if (wl.isHeld()) wl.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void threadSleep(long millis) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(millis);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
// we simply ignore if sleep was interrupted
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Taken out to helper method to allow testing
|
|
||||||
*/
|
|
||||||
public DataMap bundleToDataMap(Bundle bundle) {
|
|
||||||
return DataMap.fromBundle(bundle);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
package info.nightscout.androidaps.interaction.utils
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.PowerManager
|
||||||
|
import com.google.android.gms.wearable.DataMap
|
||||||
|
import info.nightscout.shared.logging.AAPSLogger
|
||||||
|
import info.nightscout.shared.logging.LTag
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by andy on 3/5/19.
|
||||||
|
* Adapted by dlvoy on 2019-11-06 using code from jamorham JoH class
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
class WearUtil @Inject constructor() {
|
||||||
|
|
||||||
|
@Inject lateinit var context: Context
|
||||||
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
|
|
||||||
|
private val debugWakelocks = false
|
||||||
|
private val rateLimits: MutableMap<String, Long> = HashMap()
|
||||||
|
|
||||||
|
//==============================================================================================
|
||||||
|
// Time related util methods
|
||||||
|
//==============================================================================================
|
||||||
|
fun timestamp(): Long {
|
||||||
|
return System.currentTimeMillis()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun msSince(`when`: Long): Long {
|
||||||
|
return timestamp() - `when`
|
||||||
|
}
|
||||||
|
|
||||||
|
fun msTill(`when`: Long): Long {
|
||||||
|
return `when` - timestamp()
|
||||||
|
}
|
||||||
|
|
||||||
|
//==============================================================================================
|
||||||
|
// Thread and power management utils
|
||||||
|
//==============================================================================================
|
||||||
|
// return true if below rate limit
|
||||||
|
@Synchronized fun isBelowRateLimit(named: String, onceForSeconds: Int): Boolean {
|
||||||
|
// check if over limit
|
||||||
|
if (rateLimits.containsKey(named) && timestamp() - rateLimits[named]!! < onceForSeconds * 1000) {
|
||||||
|
aapsLogger.debug(LTag.WEAR, "$named rate limited to one for $onceForSeconds seconds")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// not over limit
|
||||||
|
rateLimits[named] = timestamp()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getWakeLock(name: String, millis: Int): PowerManager.WakeLock {
|
||||||
|
val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager
|
||||||
|
val wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AAPS::$name")
|
||||||
|
wl.acquire(millis.toLong())
|
||||||
|
if (debugWakelocks) aapsLogger.debug(LTag.WEAR, "getWakeLock: $name $wl")
|
||||||
|
return wl
|
||||||
|
}
|
||||||
|
|
||||||
|
fun releaseWakeLock(wl: PowerManager.WakeLock?) {
|
||||||
|
if (debugWakelocks) aapsLogger.debug(LTag.WEAR, "releaseWakeLock: " + wl.toString())
|
||||||
|
if (wl?.isHeld == true) wl.release()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun threadSleep(millis: Long) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(millis)
|
||||||
|
} catch (e: InterruptedException) {
|
||||||
|
// we simply ignore if sleep was interrupted
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Taken out to helper method to allow testing
|
||||||
|
*/
|
||||||
|
fun bundleToDataMap(bundle: Bundle?): DataMap {
|
||||||
|
return DataMap.fromBundle(bundle)
|
||||||
|
}
|
||||||
|
}
|
|
@ -64,7 +64,7 @@ class WearUtilMocker(private val wearUtil: WearUtil) {
|
||||||
if (v is String) map.putString(key, v)
|
if (v is String) map.putString(key, v)
|
||||||
if (v is Array<*>) map.putStringArray(key, v as Array<String>)
|
if (v is Array<*>) map.putStringArray(key, v as Array<String>)
|
||||||
if (v is ArrayList<*>) {
|
if (v is ArrayList<*>) {
|
||||||
if (!v.isEmpty()) {
|
if (v.isNotEmpty()) {
|
||||||
if (v[0] is Int) {
|
if (v[0] is Int) {
|
||||||
map.putIntegerArrayList(key, v as ArrayList<Int>)
|
map.putIntegerArrayList(key, v as ArrayList<Int>)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue