KeepAlive refactor, MainApp cleanup

This commit is contained in:
Milos Kozak 2019-12-24 16:07:17 +01:00
parent 99b07521ef
commit 737a2c5386
7 changed files with 138 additions and 186 deletions

View file

@ -25,8 +25,6 @@ public class Constants {
public static final int hoursToKeepInDatabase = 72;
public static final int daysToKeepHistoryInDatabase = 30;
public static final long keepAliveMsecs = 5 * 60 * 1000L;
// SMS COMMUNICATOR
public static final long remoteBolusMinDistance = 15 * 60 * 1000L;

View file

@ -313,9 +313,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
return true;
case R.id.nav_exit:
log.debug("Exiting");
MainApp.instance().stopKeepAliveService();
RxBus.INSTANCE.send(new EventAppExit());
MainApp.closeDbHelper();
finish();
System.runFinalization();
System.exit(0);

View file

@ -1,12 +1,14 @@
package info.nightscout.androidaps;
import android.app.Application;
import android.content.BroadcastReceiver;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.os.SystemClock;
import androidx.annotation.ColorRes;
import androidx.annotation.PluralsRes;
import androidx.annotation.StringRes;
import androidx.core.content.ContextCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.crashlytics.android.Crashlytics;
@ -99,7 +101,6 @@ import static info.nightscout.androidaps.plugins.constraints.versionChecker.Vers
public class MainApp extends Application {
private static Logger log = LoggerFactory.getLogger(L.CORE);
private static KeepAliveReceiver keepAliveReceiver;
private static MainApp sInstance;
public static Resources sResources;
@ -112,9 +113,7 @@ public class MainApp extends Application {
private static ArrayList<PluginBase> pluginsList = null;
private static DataReceiver dataReceiver = new DataReceiver();
private static NSAlarmReceiver alarmReciever = new NSAlarmReceiver();
private LocalBroadcastManager lbm;
BroadcastReceiver btReceiver;
private static NSAlarmReceiver alarmReceiver = new NSAlarmReceiver();
TimeDateOrTZChangeReceiver timeDateOrTZChangeReceiver;
public static boolean devBranch;
@ -168,7 +167,6 @@ public class MainApp extends Application {
//trigger here to see the new version on app start after an update
triggerCheckVersion();
//setBTReceiver();
if (pluginsList == null) {
pluginsList = new ArrayList<>();
@ -240,10 +238,10 @@ public class MainApp extends Application {
new Thread(() -> {
SystemClock.sleep(5000);
ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("Initialization", null);
startKeepAliveService();
}).start();
}
new Thread(() -> KeepAliveReceiver.setAlarm(this)).start();
doMigrations();
}
@ -273,7 +271,7 @@ public class MainApp extends Application {
private void registerLocalBroadcastReceiver() {
lbm = LocalBroadcastManager.getInstance(this);
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_TREATMENT));
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_CHANGED_TREATMENT));
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_REMOVED_TREATMENT));
@ -288,33 +286,21 @@ public class MainApp extends Application {
lbm.registerReceiver(dataReceiver, new IntentFilter(Intents.ACTION_NEW_CAL));
//register alarms
lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_ALARM));
lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_ANNOUNCEMENT));
lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_CLEAR_ALARM));
lbm.registerReceiver(alarmReciever, new IntentFilter(Intents.ACTION_URGENT_ALARM));
lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_ALARM));
lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_ANNOUNCEMENT));
lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_CLEAR_ALARM));
lbm.registerReceiver(alarmReceiver, new IntentFilter(Intents.ACTION_URGENT_ALARM));
this.timeDateOrTZChangeReceiver = new TimeDateOrTZChangeReceiver();
this.timeDateOrTZChangeReceiver.registerBroadcasts(this);
}
private void startKeepAliveService() {
if (keepAliveReceiver == null) {
keepAliveReceiver = new KeepAliveReceiver();
keepAliveReceiver.setAlarm(this);
}
}
public void stopKeepAliveService() {
if (keepAliveReceiver != null)
KeepAliveReceiver.cancelAlarm(this);
}
public static String gs(int id) {
public static String gs(@StringRes int id) {
return sResources.getString(id);
}
public static String gs(int id, Object... args) {
public static String gs(@StringRes int id, Object... args) {
return sResources.getString(id, args);
}
@ -322,8 +308,8 @@ public class MainApp extends Application {
return sResources.getQuantityString(id, quantity, args);
}
public static int gc(int id) {
return sResources.getColor(id);
public static int gc(@ColorRes int id) {
return ContextCompat.getColor(instance(), id);
}
public static MainApp instance() {
@ -334,13 +320,6 @@ public class MainApp extends Application {
return sDatabaseHelper;
}
public static void closeDbHelper() {
if (sDatabaseHelper != null) {
sDatabaseHelper.close();
sDatabaseHelper = null;
}
}
public static FirebaseAnalytics getFirebaseAnalytics() {
return mFirebaseAnalytics;
}
@ -443,20 +422,12 @@ public class MainApp extends Application {
public void onTerminate() {
if (L.isEnabled(L.CORE))
log.debug("onTerminate");
super.onTerminate();
if (sDatabaseHelper != null) {
sDatabaseHelper.close();
sDatabaseHelper = null;
}
if (btReceiver != null) {
unregisterReceiver(btReceiver);
}
if (timeDateOrTZChangeReceiver != null) {
if (timeDateOrTZChangeReceiver != null)
unregisterReceiver(timeDateOrTZChangeReceiver);
}
unregisterActivityLifecycleCallbacks(ActivityMonitor.INSTANCE);
KeepAliveReceiver.cancelAlarm(this);
super.onTerminate();
}
public static int dpToPx(int dp) {

View file

@ -194,15 +194,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
return newVersion;
}
/**
* Close the database connections and clear any cached DAOs.
*/
@Override
public void close() {
super.close();
}
public long size(String database) {
return DatabaseUtils.queryNumEntries(getReadableDatabase(), database);
}

View file

@ -110,9 +110,7 @@ public class ImportExportPrefs {
SP.putBoolean(R.string.key_setupwizard_processed, true);
OKDialog.show(context, MainApp.gs(R.string.setting_imported), MainApp.gs(R.string.restartingapp), () -> {
log.debug("Exiting");
MainApp.instance().stopKeepAliveService();
RxBus.INSTANCE.send(new EventAppExit());
MainApp.closeDbHelper();
if (context instanceof Activity) {
((Activity) context).finish();
}

View file

@ -1,125 +0,0 @@
package info.nightscout.androidaps.receivers;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.PowerManager;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.Constants;
import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.events.EventProfileNeedsUpdate;
import info.nightscout.androidaps.interfaces.APSInterface;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.queue.commands.Command;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.LocalAlertUtils;
import info.nightscout.androidaps.utils.T;
/**
* Created by mike on 07.07.2016.
*/
public class KeepAliveReceiver extends BroadcastReceiver {
private static Logger log = LoggerFactory.getLogger(L.CORE);
public static final long STATUS_UPDATE_FREQUENCY = T.mins(15).msecs();
private static long lastReadStatus = 0;
private static long lastRun = 0;
private static long lastIobUpload = 0;
public static void cancelAlarm(Context context) {
Intent intent = new Intent(context, KeepAliveReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
@Override
public void onReceive(Context context, Intent rIntent) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AndroidAPS:KeepAliveReciever");
wl.acquire();
LocalAlertUtils.shortenSnoozeInterval();
LocalAlertUtils.checkStaleBGAlert();
checkPump();
checkAPS();
if (L.isEnabled(L.CORE))
log.debug("KeepAlive received");
wl.release();
}
private void checkAPS() {
APSInterface usedAPS = ConfigBuilderPlugin.getPlugin().getActiveAPS();
boolean shouldUploadStatus = false;
if (usedAPS == null) shouldUploadStatus = true;
else if (DateUtil.isOlderThan(usedAPS.getLastAPSRun(), 5)) shouldUploadStatus = true;
if (DateUtil.isOlderThan(lastIobUpload, 5) && shouldUploadStatus) {
lastIobUpload = DateUtil.now();
NSUpload.uploadDeviceStatus();
}
}
private void checkPump() {
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
final Profile profile = ProfileFunctions.getInstance().getProfile();
if (pump != null && profile != null) {
long lastConnection = pump.lastDataTime();
boolean isStatusOutdated = lastConnection + STATUS_UPDATE_FREQUENCY < System.currentTimeMillis();
boolean isBasalOutdated = Math.abs(profile.getBasal() - pump.getBaseBasalRate()) > pump.getPumpDescription().basalStep;
if (L.isEnabled(L.CORE))
log.debug("Last connection: " + DateUtil.dateAndTimeString(lastConnection));
// sometimes keepalive broadcast stops
// as as workaround test if readStatus was requested before an alarm is generated
if (lastReadStatus != 0 && lastReadStatus > System.currentTimeMillis() - T.mins(5).msecs()) {
LocalAlertUtils.checkPumpUnreachableAlarm(lastConnection, isStatusOutdated);
}
if (!pump.isThisProfileSet(profile) && !ConfigBuilderPlugin.getPlugin().getCommandQueue().isRunning(Command.CommandType.BASALPROFILE)) {
RxBus.INSTANCE.send(new EventProfileNeedsUpdate());
} else if (isStatusOutdated && !pump.isBusy()) {
lastReadStatus = System.currentTimeMillis();
ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("KeepAlive. Status outdated.", null);
} else if (isBasalOutdated && !pump.isBusy()) {
lastReadStatus = System.currentTimeMillis();
ConfigBuilderPlugin.getPlugin().getCommandQueue().readStatus("KeepAlive. Basal outdated.", null);
}
}
if (lastRun != 0 && System.currentTimeMillis() - lastRun > T.mins(10).msecs()) {
log.error("KeepAlive fail");
FabricPrivacy.getInstance().logCustom("KeepAliveFail");
}
lastRun = System.currentTimeMillis();
}
//called by MainApp at first app start
public void setAlarm(Context context) {
LocalAlertUtils.shortenSnoozeInterval();
LocalAlertUtils.presnoozeAlarms();
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(context, KeepAliveReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, i, 0);
try {
pi.send();
} catch (PendingIntent.CanceledException e) {
}
am.cancel(pi);
am.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), Constants.keepAliveMsecs, pi);
}
}

View file

@ -0,0 +1,121 @@
package info.nightscout.androidaps.receivers
import android.app.AlarmManager
import android.app.PendingIntent
import android.app.PendingIntent.CanceledException
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.PowerManager
import android.os.SystemClock
import info.nightscout.androidaps.events.EventProfileNeedsUpdate
import info.nightscout.androidaps.logging.L
import info.nightscout.androidaps.plugins.bus.RxBus.send
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.queue.commands.Command
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.LocalAlertUtils
import info.nightscout.androidaps.utils.T
import org.slf4j.LoggerFactory
import kotlin.math.abs
class KeepAliveReceiver : BroadcastReceiver() {
private var lastReadStatus: Long = 0
private var lastRun: Long = 0
private var lastIobUpload: Long = 0
override fun onReceive(context: Context, rIntent: Intent) {
if (L.isEnabled(L.CORE))
log.debug("KeepAlive received")
val pm = context.getSystemService(Context.POWER_SERVICE) as PowerManager
val wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "AndroidAPS:KeepAliveReceiver")
wl.acquire(T.mins(2).msecs())
LocalAlertUtils.shortenSnoozeInterval()
LocalAlertUtils.checkStaleBGAlert()
checkPump()
checkAPS()
wl.release()
}
companion object {
private val log = LoggerFactory.getLogger(L.CORE)
private val KEEP_ALIVE_MILLISECONDS = T.mins(5).msecs()
private val STATUS_UPDATE_FREQUENCY = T.mins(15).msecs()
private val IOB_UPDATE_FREQUENCY = T.mins(5).msecs()
//called by MainApp at first app start
@JvmStatic
fun setAlarm(context: Context) {
if (L.isEnabled(L.CORE))
log.debug("KeepAlive scheduled")
SystemClock.sleep(5000) // wait for app initialization
LocalAlertUtils.shortenSnoozeInterval()
LocalAlertUtils.presnoozeAlarms()
val am = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
val i = Intent(context, KeepAliveReceiver::class.java)
val pi = PendingIntent.getBroadcast(context, 0, i, 0)
try {
pi.send()
} catch (e: CanceledException) {
}
am.cancel(pi)
am.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), KEEP_ALIVE_MILLISECONDS, pi)
}
@JvmStatic
fun cancelAlarm(context: Context) {
if (L.isEnabled(L.CORE))
log.debug("KeepAlive canceled")
val intent = Intent(context, KeepAliveReceiver::class.java)
val sender = PendingIntent.getBroadcast(context, 0, intent, 0)
val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmManager.cancel(sender)
}
}
private fun checkAPS() {
val usedAPS = ConfigBuilderPlugin.getPlugin().activeAPS
var shouldUploadStatus = false
if (usedAPS == null) shouldUploadStatus = true
else if (DateUtil.isOlderThan(usedAPS.lastAPSRun, 5)) shouldUploadStatus = true
if (DateUtil.isOlderThan(lastIobUpload, IOB_UPDATE_FREQUENCY) && shouldUploadStatus) {
lastIobUpload = DateUtil.now()
NSUpload.uploadDeviceStatus()
}
}
private fun checkPump() {
val pump = ConfigBuilderPlugin.getPlugin().activePump
val profile = ProfileFunctions.getInstance().profile
if (pump != null && profile != null) {
val lastConnection = pump.lastDataTime()
val isStatusOutdated = lastConnection + STATUS_UPDATE_FREQUENCY < System.currentTimeMillis()
val isBasalOutdated = abs(profile.basal - pump.baseBasalRate) > pump.pumpDescription.basalStep
if (L.isEnabled(L.CORE))
log.debug("Last connection: " + DateUtil.dateAndTimeString(lastConnection))
// sometimes keep alive broadcast stops
// as as workaround test if readStatus was requested before an alarm is generated
if (lastReadStatus != 0L && lastReadStatus > System.currentTimeMillis() - T.mins(5).msecs()) {
LocalAlertUtils.checkPumpUnreachableAlarm(lastConnection, isStatusOutdated)
}
if (!pump.isThisProfileSet(profile) && !ConfigBuilderPlugin.getPlugin().commandQueue.isRunning(Command.CommandType.BASALPROFILE)) {
send(EventProfileNeedsUpdate())
} else if (isStatusOutdated && !pump.isBusy) {
lastReadStatus = System.currentTimeMillis()
ConfigBuilderPlugin.getPlugin().commandQueue.readStatus("KeepAlive. Status outdated.", null)
} else if (isBasalOutdated && !pump.isBusy) {
lastReadStatus = System.currentTimeMillis()
ConfigBuilderPlugin.getPlugin().commandQueue.readStatus("KeepAlive. Basal outdated.", null)
}
}
if (lastRun != 0L && System.currentTimeMillis() - lastRun > T.mins(10).msecs()) {
log.error("KeepAlive fail")
FabricPrivacy.getInstance().logCustom("KeepAliveFail")
}
lastRun = System.currentTimeMillis()
}
}