Merge branch 'dev' of github.com:MilosKozak/AndroidAPS into update-oref

This commit is contained in:
Tim Gunn 2019-11-29 19:35:24 +13:00
commit 1dbc4a7aa2
596 changed files with 18783 additions and 8766 deletions

48
CONTRIBUTING.md Normal file
View file

@ -0,0 +1,48 @@
This document speciffy hints and good practices for source code contributions.
AndroidAPS is community effort and all contributions are welcome! If you wish help us improving AndroidAPS - please read and try to adhere to
this guidelines, to make the development and process of change aproval as smooth as possible :)
General rules
=============
* There are plenty of ways you can help, some of them are listed on wiki:
https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/How-can-I-help.html
* If you wish to help with documentation or translating:
https://androidaps.readthedocs.io/en/latest/EN/translations.html
Development guidelines
======================
Coding convetions
-----------------
1. Use Android Studio with default indents (4 chars, use spaces)
2. Use autoformat feature CTRL-ALT-L in every changed file before commit
Commiting Changes / Pull Requests
---------------------------------
1. Make fork of repository on github
2. Create separate branch for each feature, branch from most recent dev
3. Commit all changes to your fork
4. When ready, rebase on top of dev and make pull request to main repo
Naming Conventions for Pull Requests / Branches
-----------------------------------------------
TODO
Translations
------------
* If possible, always use Android translation mechanism (with strings.xml and @strings/id) instead of hardcoded texts
* Provide only English strings - all other languages will be crowd translated via Crowdn https://translations.androidaps.org/
Hints
-----
* Start small, it is easier to review smaller changes that affect fewer parts of code
* Take a look into Issues list (https://github.com/MilosKozak/AndroidAPS/issues) - maybe there is somthing you can fix or implement
* For new features, make sure there is Issue to track progress and have on-topic discussion
* Reach out to community, discuss idea on Gitter (https://gitter.im/MilosKozak/AndroidAPS)
* Speak with other developers to minimise merge conflicts. Find out who worked, working or plan to work on speciffic issue or part of app

View file

@ -109,7 +109,7 @@ android {
targetSdkVersion 28 targetSdkVersion 28
multiDexEnabled true multiDexEnabled true
versionCode 1500 versionCode 1500
version "2.4-dev-g" version "2.6-dev"
buildConfigField "String", "VERSION", '"' + version + '"' buildConfigField "String", "VERSION", '"' + version + '"'
buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"' buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"'
buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"' buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"'
@ -240,8 +240,6 @@ dependencies {
implementation 'androidx.percentlayout:percentlayout:1.0.0' implementation 'androidx.percentlayout:percentlayout:1.0.0'
implementation "com.wdullaer:materialdatetimepicker:2.3.0" implementation "com.wdullaer:materialdatetimepicker:2.3.0"
// Otto bus will be replaced by rx
implementation "com.squareup:otto:1.3.7"
implementation "io.reactivex.rxjava2:rxandroid:2.1.1" implementation "io.reactivex.rxjava2:rxandroid:2.1.1"
implementation "com.j256.ormlite:ormlite-core:${ormLiteVersion}" implementation "com.j256.ormlite:ormlite-core:${ormLiteVersion}"
@ -286,9 +284,6 @@ dependencies {
testImplementation("com.google.truth:truth:0.39") { testImplementation("com.google.truth:truth:0.39") {
exclude group: "com.google.guava", module: "guava" exclude group: "com.google.guava", module: "guava"
} }
testImplementation("org.robolectric:robolectric:4.2.1") {
exclude group: "com.google.guava", module: "guava"
}
testImplementation "org.skyscreamer:jsonassert:1.5.0" testImplementation "org.skyscreamer:jsonassert:1.5.0"
testImplementation "org.hamcrest:hamcrest-all:1.3" testImplementation "org.hamcrest:hamcrest-all:1.3"
/* /*

View file

@ -1,96 +0,0 @@
package com.squareup.otto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import info.nightscout.androidaps.events.Event;
import info.nightscout.androidaps.logging.L;
/**
* Logs events has they're being posted to and dispatched from the event bus.
* <p>
* A summary of event-receiver calls that occurred so far is logged
* after 10s (after startup) and then again every 60s.
*/
public class LoggingBus extends Bus {
private static Logger log = LoggerFactory.getLogger(L.EVENTS);
private static long everyMinute = System.currentTimeMillis() + 10 * 1000;
private Map<String, Set<String>> event2Receiver = new HashMap<>();
public LoggingBus(ThreadEnforcer enforcer) {
super(enforcer);
}
@Override
public void post(Object event) {
if (event instanceof DeadEvent) {
log.debug("Event has no receiver: " + ((DeadEvent) event).event + ", source: " + ((DeadEvent) event).source);
return;
}
if (!(event instanceof Event)) {
log.error("Posted event not an event class: " + event.getClass());
}
log.debug("<<< " + event);
try {
StackTraceElement caller = new Throwable().getStackTrace()[1];
String className = caller.getClassName();
className = className.substring(className.lastIndexOf(".") + 1);
log.debug(" source: " + className + "." + caller.getMethodName() + ":" + caller.getLineNumber());
} catch (RuntimeException e) {
log.debug(" source: <unknown>");
}
try {
super.post(event);
} catch (IllegalStateException ignored) {
}
}
@Override
protected void dispatch(Object event, EventHandler wrapper) {
try {
log.debug(">>> " + event);
Field methodField = wrapper.getClass().getDeclaredField("method");
methodField.setAccessible(true);
Method targetMethod = (Method) methodField.get(wrapper);
String className = targetMethod.getDeclaringClass().getSimpleName();
String methodName = targetMethod.getName();
String receiverMethod = className + "." + methodName;
log.debug(" receiver: " + receiverMethod);
String key = event.getClass().getSimpleName();
if (!event2Receiver.containsKey(key)) event2Receiver.put(key, new HashSet<String>());
event2Receiver.get(key).add(receiverMethod);
} catch (ReflectiveOperationException e) {
log.debug(" receiver: <unknown>");
}
try {
if (everyMinute < System.currentTimeMillis()) {
log.debug("***************** Event -> receiver pairings seen so far ****************");
for (Map.Entry<String, Set<String>> stringSetEntry : event2Receiver.entrySet()) {
log.debug(" " + stringSetEntry.getKey());
for (String s : stringSetEntry.getValue()) {
log.debug(" -> " + s);
}
}
log.debug("*************************************************************************");
everyMinute = System.currentTimeMillis() + 60 * 1000;
}
} catch (ConcurrentModificationException ignored) {
}
super.dispatch(event, wrapper);
}
}

View file

@ -12,13 +12,4 @@ public class Config {
public static final boolean PUMPCONTROL = BuildConfig.FLAVOR.equals("pumpcontrol"); public static final boolean PUMPCONTROL = BuildConfig.FLAVOR.equals("pumpcontrol");
public static final boolean PUMPDRIVERS = BuildConfig.FLAVOR.equals("full") || BuildConfig.FLAVOR.equals("pumpcontrol"); public static final boolean PUMPDRIVERS = BuildConfig.FLAVOR.equals("full") || BuildConfig.FLAVOR.equals("pumpcontrol");
public static final boolean ACTION = !NSCLIENT;
public static final boolean MDI = !NSCLIENT;
public static final boolean OTHERPROFILES = !NSCLIENT;
public static final boolean SAFETY = !NSCLIENT;
public static final boolean SMSCOMMUNICATORENABLED = !NSCLIENT;
} }

View file

@ -6,7 +6,6 @@ import android.content.pm.PackageManager;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.Bundle; import android.os.Bundle;
import android.os.PersistableBundle; import android.os.PersistableBundle;
import android.os.PowerManager;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.method.LinkMovementMethod; import android.text.method.LinkMovementMethod;
import android.text.util.Linkify; import android.text.util.Linkify;
@ -21,6 +20,7 @@ import android.widget.EditText;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
@ -33,7 +33,6 @@ import com.google.android.material.navigation.NavigationView;
import com.google.android.material.tabs.TabLayout; import com.google.android.material.tabs.TabLayout;
import com.joanzapata.iconify.Iconify; import com.joanzapata.iconify.Iconify;
import com.joanzapata.iconify.fonts.FontAwesomeModule; import com.joanzapata.iconify.fonts.FontAwesomeModule;
import com.squareup.otto.Subscribe;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -45,16 +44,16 @@ import info.nightscout.androidaps.activities.PreferencesActivity;
import info.nightscout.androidaps.activities.SingleFragmentActivity; import info.nightscout.androidaps.activities.SingleFragmentActivity;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.events.EventAppExit; import info.nightscout.androidaps.events.EventAppExit;
import info.nightscout.androidaps.events.EventFeatureRunning;
import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.events.EventRefreshGui; import info.nightscout.androidaps.events.EventRebuildTabs;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtilsKt;
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSettingsStatus; 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.setupwizard.SetupWizardActivity;
import info.nightscout.androidaps.tabs.TabPageAdapter; import info.nightscout.androidaps.tabs.TabPageAdapter;
import info.nightscout.androidaps.utils.AndroidPermission; import info.nightscout.androidaps.utils.AndroidPermission;
@ -63,11 +62,12 @@ import info.nightscout.androidaps.utils.LocaleHelper;
import info.nightscout.androidaps.utils.OKDialog; import info.nightscout.androidaps.utils.OKDialog;
import info.nightscout.androidaps.utils.PasswordProtection; import info.nightscout.androidaps.utils.PasswordProtection;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SP;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
public class MainActivity extends NoSplashAppCompatActivity { public class MainActivity extends NoSplashAppCompatActivity {
private static Logger log = LoggerFactory.getLogger(L.CORE); private static Logger log = LoggerFactory.getLogger(L.CORE);
private CompositeDisposable disposable = new CompositeDisposable();
protected PowerManager.WakeLock mWakeLock;
private ActionBarDrawerToggle actionBarDrawerToggle; private ActionBarDrawerToggle actionBarDrawerToggle;
@ -77,11 +77,8 @@ public class MainActivity extends NoSplashAppCompatActivity {
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
if (L.isEnabled(L.CORE))
log.debug("onCreate");
Iconify.with(new FontAwesomeModule()); Iconify.with(new FontAwesomeModule());
LocaleHelper.onCreate(this, "en"); LocaleHelper.INSTANCE.update(getApplicationContext());
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
setSupportActionBar(findViewById(R.id.toolbar)); setSupportActionBar(findViewById(R.id.toolbar));
@ -95,14 +92,10 @@ public class MainActivity extends NoSplashAppCompatActivity {
actionBarDrawerToggle.syncState(); actionBarDrawerToggle.syncState();
// initialize screen wake lock // initialize screen wake lock
onEventPreferenceChange(new EventPreferenceChange(R.string.key_keep_screen_on)); processPreferenceChange(new EventPreferenceChange(R.string.key_keep_screen_on));
doMigrations(); doMigrations();
registerBus();
setupTabs();
setupViews(false);
final ViewPager viewPager = findViewById(R.id.pager); final ViewPager viewPager = findViewById(R.id.pager);
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() { viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override @Override
@ -124,6 +117,43 @@ public class MainActivity extends NoSplashAppCompatActivity {
VersionCheckerUtilsKt.triggerCheckVersion(); VersionCheckerUtilsKt.triggerCheckVersion();
FabricPrivacy.setUserStats(); FabricPrivacy.setUserStats();
setupTabs();
setupViews();
disposable.add(RxBus.INSTANCE
.toObservable(EventRebuildTabs.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> {
LocaleHelper.INSTANCE.update(getApplicationContext());
if (event.getRecreate()) {
recreate();
} else {
setupTabs();
setupViews();
}
setWakeLock();
}, FabricPrivacy::logException)
);
disposable.add(RxBus.INSTANCE
.toObservable(EventPreferenceChange.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::processPreferenceChange, FabricPrivacy::logException)
);
if (!SP.getBoolean(R.string.key_setupwizard_processed, false)) {
Intent intent = new Intent(this, SetupWizardActivity.class);
startActivity(intent);
} else {
checkEula();
}
AndroidPermission.notifyForStoragePermission(this);
AndroidPermission.notifyForBatteryOptimizationPermission(this);
if (Config.PUMPDRIVERS) {
AndroidPermission.notifyForLocationPermissions(this);
AndroidPermission.notifyForSMSPermissions(this);
}
} }
private void checkPluginPreferences(ViewPager viewPager) { private void checkPluginPreferences(ViewPager viewPager) {
@ -139,86 +169,29 @@ public class MainActivity extends NoSplashAppCompatActivity {
actionBarDrawerToggle.syncState(); actionBarDrawerToggle.syncState();
} }
@Override
protected void onResume() {
super.onResume();
if (L.isEnabled(L.CORE))
log.debug("onResume");
if (!SP.getBoolean(R.string.key_setupwizard_processed, false)) {
Intent intent = new Intent(this, SetupWizardActivity.class);
startActivity(intent);
} else {
checkEula();
}
AndroidPermission.notifyForStoragePermission(this);
AndroidPermission.notifyForBatteryOptimizationPermission(this);
if (Config.PUMPDRIVERS) {
AndroidPermission.notifyForLocationPermissions(this);
AndroidPermission.notifyForSMSPermissions(this);
}
MainApp.bus().post(new EventFeatureRunning(EventFeatureRunning.Feature.MAIN));
}
@Override @Override
public void onDestroy() { public void onDestroy() {
if (L.isEnabled(L.CORE))
log.debug("onDestroy");
if (mWakeLock != null)
if (mWakeLock.isHeld())
mWakeLock.release();
super.onDestroy(); super.onDestroy();
disposable.clear();
} }
@Subscribe private void setWakeLock() {
public void onEventPreferenceChange(final EventPreferenceChange ev) { boolean keepScreenOn = SP.getBoolean(R.string.key_keep_screen_on, false);
if (ev.isChanged(R.string.key_keep_screen_on)) { if (keepScreenOn)
boolean keepScreenOn = SP.getBoolean(R.string.key_keep_screen_on, false); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); else
if (keepScreenOn) { getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "AndroidAPS:MainActivity_onEventPreferenceChange");
if (!mWakeLock.isHeld())
mWakeLock.acquire();
} else {
if (mWakeLock != null && mWakeLock.isHeld())
mWakeLock.release();
}
}
} }
@Subscribe public void processPreferenceChange(final EventPreferenceChange ev) {
public void onStatusEvent(final EventRefreshGui ev) { if (ev.isChanged(R.string.key_keep_screen_on))
String lang = SP.getString(R.string.key_language, "en"); setWakeLock();
LocaleHelper.setLocale(getApplicationContext(), lang);
runOnUiThread(() -> {
if (ev.recreate) {
recreate();
} else {
try { // activity may be destroyed
setupTabs();
setupViews(false);
} catch (IllegalStateException e) {
log.error("Unhandled exception", e);
}
}
boolean keepScreenOn = Config.NSCLIENT && SP.getBoolean(R.string.key_keep_screen_on, false);
if (keepScreenOn)
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
else
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
});
} }
private void setupViews(boolean switchToLast) { private void setupViews() {
TabPageAdapter pageAdapter = new TabPageAdapter(getSupportFragmentManager(), this); TabPageAdapter pageAdapter = new TabPageAdapter(getSupportFragmentManager(), this);
NavigationView navigationView = findViewById(R.id.navigation_view); NavigationView navigationView = findViewById(R.id.navigation_view);
navigationView.setNavigationItemSelectedListener(menuItem -> { navigationView.setNavigationItemSelectedListener(menuItem -> true);
return true;
});
Menu menu = navigationView.getMenu(); Menu menu = navigationView.getMenu();
menu.clear(); menu.clear();
for (PluginBase p : MainApp.getPluginsList()) { for (PluginBase p : MainApp.getPluginsList()) {
@ -237,8 +210,8 @@ public class MainActivity extends NoSplashAppCompatActivity {
} }
ViewPager mPager = findViewById(R.id.pager); ViewPager mPager = findViewById(R.id.pager);
mPager.setAdapter(pageAdapter); mPager.setAdapter(pageAdapter);
if (switchToLast) //if (switchToLast)
mPager.setCurrentItem(pageAdapter.getCount() - 1, false); // mPager.setCurrentItem(pageAdapter.getCount() - 1, false);
checkPluginPreferences(mPager); checkPluginPreferences(mPager);
} }
@ -264,15 +237,6 @@ public class MainActivity extends NoSplashAppCompatActivity {
} }
} }
private void registerBus() {
try {
MainApp.bus().unregister(this);
} catch (RuntimeException x) {
// Ignore
}
MainApp.bus().register(this);
}
private void checkEula() { private void checkEula() {
//SP.removeBoolean(R.string.key_i_understand); //SP.removeBoolean(R.string.key_i_understand);
boolean IUnderstand = SP.getBoolean(R.string.key_i_understand, false); boolean IUnderstand = SP.getBoolean(R.string.key_i_understand, false);
@ -289,10 +253,10 @@ public class MainActivity extends NoSplashAppCompatActivity {
// guarantee that the unreachable threshold is at least 30 and of type String // guarantee that the unreachable threshold is at least 30 and of type String
// Added in 1.57 at 21.01.2018 // Added in 1.57 at 21.01.2018
Integer unreachable_threshold = SP.getInt(R.string.key_pump_unreachable_threshold, 30); int unreachable_threshold = SP.getInt(R.string.key_pump_unreachable_threshold, 30);
SP.remove(R.string.key_pump_unreachable_threshold); SP.remove(R.string.key_pump_unreachable_threshold);
if (unreachable_threshold < 30) unreachable_threshold = 30; if (unreachable_threshold < 30) unreachable_threshold = 30;
SP.putString(R.string.key_pump_unreachable_threshold, unreachable_threshold.toString()); SP.putString(R.string.key_pump_unreachable_threshold, Integer.toString(unreachable_threshold));
} }
@ -308,19 +272,16 @@ public class MainActivity extends NoSplashAppCompatActivity {
String message = "Target range is changed in current version.\n\nIt's not taken from preferences but from profile.\n\n!!! REVIEW YOUR SETTINGS !!!"; String message = "Target range is changed in current version.\n\nIt's not taken from preferences but from profile.\n\n!!! REVIEW YOUR SETTINGS !!!";
message += "\n\nOld settings: " + oldRange; message += "\n\nOld settings: " + oldRange;
message += "\nProfile settings: " + newRange; message += "\nProfile settings: " + newRange;
OKDialog.show(this, "Target range change", message, new Runnable() { OKDialog.show(this, "Target range change", message, () -> {
@Override SP.remove("openapsma_min_bg");
public void run() { SP.remove("openapsma_max_bg");
SP.remove("openapsma_min_bg"); SP.remove("openapsma_target_bg");
SP.remove("openapsma_max_bg");
SP.remove("openapsma_target_bg");
}
}); });
} }
} }
@Override @Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults); super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (permissions.length != 0) { if (permissions.length != 0) {
if (ActivityCompat.checkSelfPermission(this, permissions[0]) == PackageManager.PERMISSION_GRANTED) { if (ActivityCompat.checkSelfPermission(this, permissions[0]) == PackageManager.PERMISSION_GRANTED) {
@ -405,7 +366,7 @@ public class MainActivity extends NoSplashAppCompatActivity {
case R.id.nav_exit: case R.id.nav_exit:
log.debug("Exiting"); log.debug("Exiting");
MainApp.instance().stopKeepAliveService(); MainApp.instance().stopKeepAliveService();
MainApp.bus().post(new EventAppExit()); RxBus.INSTANCE.send(new EventAppExit());
MainApp.closeDbHelper(); MainApp.closeDbHelper();
finish(); finish();
System.runFinalization(); System.runFinalization();

View file

@ -6,16 +6,12 @@ import android.content.IntentFilter;
import android.content.res.Resources; import android.content.res.Resources;
import android.os.SystemClock; import android.os.SystemClock;
import androidx.annotation.Nullable;
import androidx.annotation.PluralsRes; import androidx.annotation.PluralsRes;
import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.localbroadcastmanager.content.LocalBroadcastManager;
import com.crashlytics.android.Crashlytics; import com.crashlytics.android.Crashlytics;
import com.google.firebase.analytics.FirebaseAnalytics; import com.google.firebase.analytics.FirebaseAnalytics;
import com.j256.ormlite.android.apptools.OpenHelperManager; import com.j256.ormlite.android.apptools.OpenHelperManager;
import com.squareup.otto.Bus;
import com.squareup.otto.LoggingBus;
import com.squareup.otto.ThreadEnforcer;
import net.danlew.android.joda.JodaTimeAndroid; import net.danlew.android.joda.JodaTimeAndroid;
@ -39,7 +35,9 @@ import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.constraints.dstHelper.DstHelperPlugin; import info.nightscout.androidaps.plugins.constraints.dstHelper.DstHelperPlugin;
import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin; import info.nightscout.androidaps.plugins.constraints.objectives.ObjectivesPlugin;
import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin; import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin;
import info.nightscout.androidaps.plugins.constraints.signatureVerifier.SignatureVerifierPlugin;
import info.nightscout.androidaps.plugins.constraints.storage.StorageConstraintPlugin; import info.nightscout.androidaps.plugins.constraints.storage.StorageConstraintPlugin;
import info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerPlugin;
import info.nightscout.androidaps.plugins.general.actions.ActionsPlugin; import info.nightscout.androidaps.plugins.general.actions.ActionsPlugin;
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin; import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin;
import info.nightscout.androidaps.plugins.general.careportal.CareportalPlugin; import info.nightscout.androidaps.plugins.general.careportal.CareportalPlugin;
@ -52,9 +50,7 @@ import info.nightscout.androidaps.plugins.general.nsclient.receivers.AckAlarmRec
import info.nightscout.androidaps.plugins.general.nsclient.receivers.DBAccessReceiver; import info.nightscout.androidaps.plugins.general.nsclient.receivers.DBAccessReceiver;
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin; import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin;
import info.nightscout.androidaps.plugins.general.persistentNotification.PersistentNotificationPlugin; import info.nightscout.androidaps.plugins.general.persistentNotification.PersistentNotificationPlugin;
import info.nightscout.androidaps.plugins.general.signatureVerifier.SignatureVerifier;
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin; 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.wear.WearPlugin;
import info.nightscout.androidaps.plugins.general.xdripStatusline.StatuslinePlugin; import info.nightscout.androidaps.plugins.general.xdripStatusline.StatuslinePlugin;
import info.nightscout.androidaps.plugins.insulin.InsulinOrefFreePeakPlugin; import info.nightscout.androidaps.plugins.insulin.InsulinOrefFreePeakPlugin;
@ -92,16 +88,16 @@ import info.nightscout.androidaps.receivers.NSAlarmReceiver;
import info.nightscout.androidaps.receivers.TimeDateOrTZChangeReceiver; import info.nightscout.androidaps.receivers.TimeDateOrTZChangeReceiver;
import info.nightscout.androidaps.services.Intents; import info.nightscout.androidaps.services.Intents;
import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.LocaleHelper;
import io.fabric.sdk.android.Fabric; import io.fabric.sdk.android.Fabric;
import static info.nightscout.androidaps.plugins.general.versionChecker.VersionCheckerUtilsKt.triggerCheckVersion; import static info.nightscout.androidaps.plugins.constraints.versionChecker.VersionCheckerUtilsKt.triggerCheckVersion;
public class MainApp extends Application { public class MainApp extends Application {
private static Logger log = LoggerFactory.getLogger(L.CORE); private static Logger log = LoggerFactory.getLogger(L.CORE);
private static KeepAliveReceiver keepAliveReceiver; private static KeepAliveReceiver keepAliveReceiver;
private static Bus sBus;
private static MainApp sInstance; private static MainApp sInstance;
public static Resources sResources; public static Resources sResources;
@ -129,10 +125,18 @@ public class MainApp extends Application {
log.debug("onCreate"); log.debug("onCreate");
sInstance = this; sInstance = this;
sResources = getResources(); sResources = getResources();
LocaleHelper.INSTANCE.update(this);
sConstraintsChecker = new ConstraintChecker(); sConstraintsChecker = new ConstraintChecker();
sDatabaseHelper = OpenHelperManager.getHelper(sInstance, DatabaseHelper.class); sDatabaseHelper = OpenHelperManager.getHelper(sInstance, DatabaseHelper.class);
Thread.setDefaultUncaughtExceptionHandler((thread, ex) -> log.error("Uncaught exception crashing app", ex)); Thread.setDefaultUncaughtExceptionHandler((thread, ex) -> {
if (ex instanceof InternalError) {
// usually the app trying to spawn a thread while being killed
return;
}
log.error("Uncaught exception crashing app", ex);
});
try { try {
if (FabricPrivacy.fabricEnabled()) { if (FabricPrivacy.fabricEnabled()) {
@ -157,8 +161,6 @@ public class MainApp extends Application {
engineeringMode = engineeringModeSemaphore.exists() && engineeringModeSemaphore.isFile(); engineeringMode = engineeringModeSemaphore.exists() && engineeringModeSemaphore.isFile();
devBranch = BuildConfig.VERSION.contains("-") || BuildConfig.VERSION.matches(".*[a-zA-Z]+.*"); devBranch = BuildConfig.VERSION.contains("-") || BuildConfig.VERSION.matches(".*[a-zA-Z]+.*");
sBus = L.isEnabled(L.EVENTS) && devBranch ? new LoggingBus(ThreadEnforcer.ANY) : new Bus(ThreadEnforcer.ANY);
registerLocalBroadcastReceiver(); registerLocalBroadcastReceiver();
//trigger here to see the new version on app start after an update //trigger here to see the new version on app start after an update
@ -170,7 +172,7 @@ public class MainApp extends Application {
// Register all tabs in app here // Register all tabs in app here
pluginsList.add(OverviewPlugin.INSTANCE); pluginsList.add(OverviewPlugin.INSTANCE);
pluginsList.add(IobCobCalculatorPlugin.getPlugin()); pluginsList.add(IobCobCalculatorPlugin.getPlugin());
if (Config.ACTION) pluginsList.add(ActionsPlugin.INSTANCE); if (!Config.NSCLIENT) pluginsList.add(ActionsPlugin.INSTANCE);
pluginsList.add(InsulinOrefRapidActingPlugin.getPlugin()); pluginsList.add(InsulinOrefRapidActingPlugin.getPlugin());
pluginsList.add(InsulinOrefUltraRapidActingPlugin.getPlugin()); pluginsList.add(InsulinOrefUltraRapidActingPlugin.getPlugin());
pluginsList.add(InsulinOrefFreePeakPlugin.getPlugin()); pluginsList.add(InsulinOrefFreePeakPlugin.getPlugin());
@ -183,24 +185,23 @@ public class MainApp extends Application {
if (Config.PUMPDRIVERS) pluginsList.add(DanaRv2Plugin.getPlugin()); if (Config.PUMPDRIVERS) pluginsList.add(DanaRv2Plugin.getPlugin());
if (Config.PUMPDRIVERS) pluginsList.add(DanaRSPlugin.getPlugin()); if (Config.PUMPDRIVERS) pluginsList.add(DanaRSPlugin.getPlugin());
if (Config.PUMPDRIVERS) pluginsList.add(LocalInsightPlugin.getPlugin()); if (Config.PUMPDRIVERS) pluginsList.add(LocalInsightPlugin.getPlugin());
pluginsList.add(CareportalPlugin.getPlugin());
if (Config.PUMPDRIVERS) pluginsList.add(ComboPlugin.getPlugin()); if (Config.PUMPDRIVERS) pluginsList.add(ComboPlugin.getPlugin());
if (Config.PUMPDRIVERS && engineeringMode) if (Config.PUMPDRIVERS) pluginsList.add(MedtronicPumpPlugin.getPlugin());
pluginsList.add(MedtronicPumpPlugin.getPlugin()); if (!Config.NSCLIENT) pluginsList.add(MDIPlugin.getPlugin());
if (Config.MDI) pluginsList.add(MDIPlugin.getPlugin());
pluginsList.add(VirtualPumpPlugin.getPlugin()); pluginsList.add(VirtualPumpPlugin.getPlugin());
pluginsList.add(CareportalPlugin.getPlugin());
if (Config.APS) pluginsList.add(LoopPlugin.getPlugin()); if (Config.APS) pluginsList.add(LoopPlugin.getPlugin());
if (Config.APS) pluginsList.add(OpenAPSMAPlugin.getPlugin()); if (Config.APS) pluginsList.add(OpenAPSMAPlugin.getPlugin());
if (Config.APS) pluginsList.add(OpenAPSAMAPlugin.getPlugin()); if (Config.APS) pluginsList.add(OpenAPSAMAPlugin.getPlugin());
if (Config.APS) pluginsList.add(OpenAPSSMBPlugin.getPlugin()); if (Config.APS) pluginsList.add(OpenAPSSMBPlugin.getPlugin());
pluginsList.add(NSProfilePlugin.getPlugin()); pluginsList.add(NSProfilePlugin.getPlugin());
if (Config.OTHERPROFILES) pluginsList.add(SimpleProfilePlugin.getPlugin()); if (!Config.NSCLIENT) pluginsList.add(SimpleProfilePlugin.getPlugin());
if (Config.OTHERPROFILES) pluginsList.add(LocalProfilePlugin.getPlugin()); if (!Config.NSCLIENT) pluginsList.add(LocalProfilePlugin.getPlugin());
pluginsList.add(TreatmentsPlugin.getPlugin()); pluginsList.add(TreatmentsPlugin.getPlugin());
if (Config.SAFETY) pluginsList.add(SafetyPlugin.getPlugin()); if (!Config.NSCLIENT) pluginsList.add(SafetyPlugin.getPlugin());
if (Config.SAFETY) pluginsList.add(VersionCheckerPlugin.INSTANCE); if (!Config.NSCLIENT) pluginsList.add(VersionCheckerPlugin.INSTANCE);
if (Config.SAFETY) pluginsList.add(StorageConstraintPlugin.getPlugin()); if (Config.APS) pluginsList.add(StorageConstraintPlugin.getPlugin());
if (Config.SAFETY) pluginsList.add(SignatureVerifier.getPlugin()); if (Config.APS) pluginsList.add(SignatureVerifierPlugin.getPlugin());
if (Config.APS) pluginsList.add(ObjectivesPlugin.INSTANCE); if (Config.APS) pluginsList.add(ObjectivesPlugin.INSTANCE);
pluginsList.add(SourceXdripPlugin.getPlugin()); pluginsList.add(SourceXdripPlugin.getPlugin());
pluginsList.add(SourceNSClientPlugin.getPlugin()); pluginsList.add(SourceNSClientPlugin.getPlugin());
@ -210,7 +211,7 @@ public class MainApp extends Application {
pluginsList.add(SourcePoctechPlugin.getPlugin()); pluginsList.add(SourcePoctechPlugin.getPlugin());
pluginsList.add(SourceTomatoPlugin.getPlugin()); pluginsList.add(SourceTomatoPlugin.getPlugin());
pluginsList.add(SourceEversensePlugin.getPlugin()); pluginsList.add(SourceEversensePlugin.getPlugin());
if (Config.SMSCOMMUNICATORENABLED) pluginsList.add(SmsCommunicatorPlugin.getPlugin()); if (!Config.NSCLIENT) pluginsList.add(SmsCommunicatorPlugin.INSTANCE);
pluginsList.add(FoodPlugin.getPlugin()); pluginsList.add(FoodPlugin.getPlugin());
pluginsList.add(WearPlugin.initPlugin(this)); pluginsList.add(WearPlugin.initPlugin(this));
@ -285,10 +286,6 @@ public class MainApp extends Application {
KeepAliveReceiver.cancelAlarm(this); KeepAliveReceiver.cancelAlarm(this);
} }
public static Bus bus() {
return sBus;
}
public static String gs(int id) { public static String gs(int id) {
return sResources.getString(id); return sResources.getString(id);
} }
@ -390,19 +387,6 @@ public class MainApp extends Application {
return newList; return newList;
} }
@Nullable
public static <T extends PluginBase> T getSpecificPlugin(Class<T> pluginClass) {
if (pluginsList != null) {
for (PluginBase p : pluginsList) {
if (pluginClass.isAssignableFrom(p.getClass()))
return (T) p;
}
} else {
log.error("pluginsList=null");
}
return null;
}
public static boolean isEngineeringModeOrRelease() { public static boolean isEngineeringModeOrRelease() {
if (!Config.APS) if (!Config.APS)
return true; return true;

View file

@ -16,7 +16,6 @@ import androidx.appcompat.widget.PopupMenu;
import androidx.core.content.res.ResourcesCompat; import androidx.core.content.res.ResourcesCompat;
import com.jjoe64.graphview.GraphView; import com.jjoe64.graphview.GraphView;
import com.squareup.otto.Subscribe;
import com.wdullaer.materialdatetimepicker.date.DatePickerDialog; import com.wdullaer.materialdatetimepicker.date.DatePickerDialog;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -30,6 +29,7 @@ import info.nightscout.androidaps.R;
import info.nightscout.androidaps.data.Profile; import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.events.EventCustomCalculationFinished; import info.nightscout.androidaps.events.EventCustomCalculationFinished;
import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.overview.OverviewFragment; import info.nightscout.androidaps.plugins.general.overview.OverviewFragment;
@ -39,12 +39,15 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorP
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventIobCalculationProgress;
import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.utils.T; import info.nightscout.androidaps.utils.T;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
public class HistoryBrowseActivity extends NoSplashActivity { public class HistoryBrowseActivity extends NoSplashActivity {
private static Logger log = LoggerFactory.getLogger(HistoryBrowseActivity.class); private static Logger log = LoggerFactory.getLogger(HistoryBrowseActivity.class);
private CompositeDisposable disposable = new CompositeDisposable();
ImageButton chartButton; ImageButton chartButton;
@ -165,14 +168,33 @@ public class HistoryBrowseActivity extends NoSplashActivity {
@Override @Override
public void onPause() { public void onPause() {
super.onPause(); super.onPause();
MainApp.bus().unregister(this); disposable.clear();
iobCobCalculatorPlugin.stopCalculation("onPause"); iobCobCalculatorPlugin.stopCalculation("onPause");
} }
@Override @Override
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
MainApp.bus().register(this); disposable.add(RxBus.INSTANCE
.toObservable(EventAutosensCalculationFinished.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> {
if (event.getCause() == eventCustomCalculationFinished) {
log.debug("EventAutosensCalculationFinished");
synchronized (HistoryBrowseActivity.this) {
updateGUI("EventAutosensCalculationFinished");
}
}
}, FabricPrivacy::logException)
);
disposable.add(RxBus.INSTANCE
.toObservable(EventIobCalculationProgress.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> {
if (iobCalculationProgressView != null)
iobCalculationProgressView.setText(event.getProgress());
}, FabricPrivacy::logException)
);
// set start of current day // set start of current day
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis()); calendar.setTimeInMillis(System.currentTimeMillis());
@ -193,26 +215,6 @@ public class HistoryBrowseActivity extends NoSplashActivity {
iobCobCalculatorPlugin.runCalculation(from, end, true, false, eventCustomCalculationFinished); iobCobCalculatorPlugin.runCalculation(from, end, true, false, eventCustomCalculationFinished);
} }
@Subscribe
public void onStatusEvent(final EventAutosensCalculationFinished e) {
if (e.getCause() == eventCustomCalculationFinished) {
log.debug("EventAutosensCalculationFinished");
runOnUiThread(() -> {
synchronized (HistoryBrowseActivity.this) {
updateGUI("EventAutosensCalculationFinished");
}
});
}
}
@Subscribe
public void onStatusEvent(final EventIobCalculationProgress e) {
runOnUiThread(() -> {
if (iobCalculationProgressView != null)
iobCalculationProgressView.setText(e.progress);
});
}
void updateGUI(String from) { void updateGUI(String from) {
log.debug("updateGUI from: " + from); log.debug("updateGUI from: " + from);

View file

@ -9,27 +9,28 @@ import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment; import android.preference.PreferenceFragment;
import android.preference.PreferenceGroup; import android.preference.PreferenceGroup;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.preference.PreferenceScreen;
import android.text.TextUtils;
import info.nightscout.androidaps.Config; import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventPreferenceChange;
import info.nightscout.androidaps.events.EventRefreshGui; import info.nightscout.androidaps.events.EventRebuildTabs;
import info.nightscout.androidaps.interfaces.PluginBase; import info.nightscout.androidaps.interfaces.PluginBase;
import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PluginType;
import info.nightscout.androidaps.plugins.general.careportal.CareportalPlugin;
import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin;
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin;
import info.nightscout.androidaps.plugins.general.tidepool.comm.TidepoolUploader;
import info.nightscout.androidaps.plugins.insulin.InsulinOrefFreePeakPlugin;
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin;
import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin; import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin;
import info.nightscout.androidaps.plugins.aps.openAPSMA.OpenAPSMAPlugin; import info.nightscout.androidaps.plugins.aps.openAPSMA.OpenAPSMAPlugin;
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin; import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.constraints.safety.SafetyPlugin;
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin;
import info.nightscout.androidaps.plugins.general.careportal.CareportalPlugin;
import info.nightscout.androidaps.plugins.general.nsclient.NSClientPlugin;
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin;
import info.nightscout.androidaps.plugins.general.tidepool.TidepoolPlugin;
import info.nightscout.androidaps.plugins.general.wear.WearPlugin;
import info.nightscout.androidaps.plugins.general.xdripStatusline.StatuslinePlugin;
import info.nightscout.androidaps.plugins.insulin.InsulinOrefFreePeakPlugin;
import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin; import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin;
import info.nightscout.androidaps.plugins.pump.danaR.DanaRPlugin; import info.nightscout.androidaps.plugins.pump.danaR.DanaRPlugin;
import info.nightscout.androidaps.plugins.pump.danaRKorean.DanaRKoreanPlugin; import info.nightscout.androidaps.plugins.pump.danaRKorean.DanaRKoreanPlugin;
@ -42,14 +43,9 @@ import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin;
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref0Plugin; import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref0Plugin;
import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin; import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin;
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin; import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin;
import info.nightscout.androidaps.plugins.general.smsCommunicator.SmsCommunicatorPlugin;
import info.nightscout.androidaps.plugins.general.wear.WearPlugin;
import info.nightscout.androidaps.plugins.general.xdripStatusline.StatuslinePlugin;
import info.nightscout.androidaps.plugins.source.SourceDexcomPlugin; import info.nightscout.androidaps.plugins.source.SourceDexcomPlugin;
import info.nightscout.androidaps.utils.LocaleHelper;
import info.nightscout.androidaps.utils.OKDialog; import info.nightscout.androidaps.utils.OKDialog;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin;
public class PreferencesActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener { public class PreferencesActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
MyPreferenceFragment myPreferenceFragment; MyPreferenceFragment myPreferenceFragment;
@ -68,22 +64,19 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
MainApp.bus().post(new EventPreferenceChange(key));
RxBus.INSTANCE.send(new EventPreferenceChange(key)); RxBus.INSTANCE.send(new EventPreferenceChange(key));
if (key.equals("language")) { if (key.equals("language")) {
String lang = sharedPreferences.getString("language", "en"); RxBus.INSTANCE.send(new EventRebuildTabs(true));
LocaleHelper.setLocale(getApplicationContext(), lang);
MainApp.bus().post(new EventRefreshGui(true));
//recreate() does not update language so better close settings //recreate() does not update language so better close settings
finish(); finish();
} }
if (key.equals("short_tabtitles")) { if (key.equals("short_tabtitles")) {
MainApp.bus().post(new EventRefreshGui()); RxBus.INSTANCE.send(new EventRebuildTabs());
} }
if (key.equals(MainApp.gs(R.string.key_openapsama_useautosens)) && SP.getBoolean(R.string.key_openapsama_useautosens, false)) { if (key.equals(MainApp.gs(R.string.key_openapsama_useautosens)) && SP.getBoolean(R.string.key_openapsama_useautosens, false)) {
OKDialog.show(this, MainApp.gs(R.string.configbuilder_sensitivity), MainApp.gs(R.string.sensitivity_warning), null); OKDialog.show(this, MainApp.gs(R.string.configbuilder_sensitivity), MainApp.gs(R.string.sensitivity_warning), null);
} }
updatePrefSummary(myPreferenceFragment.getPreference(key)); updatePrefSummary(myPreferenceFragment.findPreference(key));
} }
private static void updatePrefSummary(Preference pref) { private static void updatePrefSummary(Preference pref) {
@ -95,13 +88,13 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
EditTextPreference editTextPref = (EditTextPreference) pref; EditTextPreference editTextPref = (EditTextPreference) pref;
if (pref.getKey().contains("password") || pref.getKey().contains("secret")) { if (pref.getKey().contains("password") || pref.getKey().contains("secret")) {
pref.setSummary("******"); pref.setSummary("******");
} else if (pref.getKey().equals(MainApp.gs(R.string.key_danars_name))) {
pref.setSummary(SP.getString(R.string.key_danars_name, ""));
} else if (editTextPref.getText() != null) { } else if (editTextPref.getText() != null) {
((EditTextPreference) pref).setDialogMessage(editTextPref.getDialogMessage()); ((EditTextPreference) pref).setDialogMessage(editTextPref.getDialogMessage());
pref.setSummary(editTextPref.getText()); pref.setSummary(editTextPref.getText());
} else if (pref.getKey().contains("smscommunicator_allowednumbers") && (editTextPref.getText() == null || TextUtils.isEmpty(editTextPref.getText().trim()))) { } else {
pref.setSummary(MainApp.gs(R.string.smscommunicator_allowednumbers_summary)); for (PluginBase plugin : MainApp.getPluginsList()) {
plugin.updatePreferenceSummary(pref);
}
} }
} }
} }
@ -191,7 +184,7 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
addPreferencesFromResourceIfEnabled(NSClientPlugin.getPlugin(), PluginType.GENERAL); addPreferencesFromResourceIfEnabled(NSClientPlugin.getPlugin(), PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(TidepoolPlugin.INSTANCE, PluginType.GENERAL); addPreferencesFromResourceIfEnabled(TidepoolPlugin.INSTANCE, PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(SmsCommunicatorPlugin.getPlugin(), PluginType.GENERAL); addPreferencesFromResourceIfEnabled(SmsCommunicatorPlugin.INSTANCE, PluginType.GENERAL);
addPreferencesFromResourceIfEnabled(AutomationPlugin.INSTANCE, PluginType.GENERAL); addPreferencesFromResourceIfEnabled(AutomationPlugin.INSTANCE, PluginType.GENERAL);
addPreferencesFromResource(R.xml.pref_others); addPreferencesFromResource(R.xml.pref_others);
@ -201,26 +194,11 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
addPreferencesFromResourceIfEnabled(StatuslinePlugin.getPlugin(), PluginType.GENERAL); addPreferencesFromResourceIfEnabled(StatuslinePlugin.getPlugin(), PluginType.GENERAL);
} }
if (Config.NSCLIENT) {
PreferenceScreen scrnAdvancedSettings = (PreferenceScreen) findPreference(getString(R.string.key_advancedsettings));
if (scrnAdvancedSettings != null) {
scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_statuslights_res_warning)));
scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_statuslights_res_critical)));
scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_statuslights_bat_warning)));
scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_statuslights_bat_critical)));
scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_show_statuslights)));
scrnAdvancedSettings.removePreference(getPreference(getString(R.string.key_show_statuslights_extended)));
}
}
initSummary(getPreferenceScreen()); initSummary(getPreferenceScreen());
final Preference tidepoolTestLogin = findPreference(MainApp.gs(R.string.key_tidepool_test_login)); for (PluginBase plugin : MainApp.getPluginsList()) {
if (tidepoolTestLogin != null) plugin.preprocessPreferences(this);
tidepoolTestLogin.setOnPreferenceClickListener(preference -> { }
TidepoolUploader.INSTANCE.testLogin(getActivity());
return false;
});
} }
@Override @Override
@ -228,9 +206,5 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre
super.onSaveInstanceState(outState); super.onSaveInstanceState(outState);
outState.putInt("id", id); outState.putInt("id", id);
} }
public Preference getPreference(String key) {
return findPreference(key);
}
} }
} }

View file

@ -1,10 +1,8 @@
package info.nightscout.androidaps.activities; package info.nightscout.androidaps.activities;
import android.app.Activity;
import android.graphics.Color; import android.graphics.Color;
import android.graphics.Rect; import android.graphics.Rect;
import android.os.Bundle; import android.os.Bundle;
import androidx.recyclerview.widget.LinearLayoutManager;
import android.text.TextUtils; import android.text.TextUtils;
import android.view.KeyEvent; import android.view.KeyEvent;
import android.view.MotionEvent; import android.view.MotionEvent;
@ -18,7 +16,7 @@ import android.widget.TableLayout;
import android.widget.TableRow; import android.widget.TableRow;
import android.widget.TextView; import android.widget.TextView;
import com.squareup.otto.Subscribe; import androidx.recyclerview.widget.LinearLayoutManager;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -39,6 +37,7 @@ import info.nightscout.androidaps.data.Profile;
import info.nightscout.androidaps.db.TDD; import info.nightscout.androidaps.db.TDD;
import info.nightscout.androidaps.events.EventPumpStatusChanged; import info.nightscout.androidaps.events.EventPumpStatusChanged;
import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.pump.danaR.DanaRPlugin; import info.nightscout.androidaps.plugins.pump.danaR.DanaRPlugin;
@ -49,11 +48,15 @@ import info.nightscout.androidaps.plugins.pump.danaRv2.DanaRv2Plugin;
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin; import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin;
import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.utils.DecimalFormatter; import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.utils.SafeParse; import info.nightscout.androidaps.utils.SafeParse;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
public class TDDStatsActivity extends NoSplashActivity { public class TDDStatsActivity extends NoSplashActivity {
private static Logger log = LoggerFactory.getLogger(TDDStatsActivity.class); private static Logger log = LoggerFactory.getLogger(TDDStatsActivity.class);
private CompositeDisposable disposable = new CompositeDisposable();
TextView statusView, statsMessage, totalBaseBasal2; TextView statusView, statsMessage, totalBaseBasal2;
EditText totalBaseBasal; EditText totalBaseBasal;
@ -74,13 +77,25 @@ public class TDDStatsActivity extends NoSplashActivity {
@Override @Override
protected void onResume() { protected void onResume() {
super.onResume(); super.onResume();
MainApp.bus().register(this); disposable.add(RxBus.INSTANCE
.toObservable(EventPumpStatusChanged.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> statusView.setText(event.getStatus()), FabricPrivacy::logException)
);
disposable.add(RxBus.INSTANCE
.toObservable(EventDanaRSyncStatus.class)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(event -> {
log.debug("EventDanaRSyncStatus: " + event.getMessage());
statusView.setText(event.getMessage());
}, FabricPrivacy::logException)
);
} }
@Override @Override
protected void onPause() { protected void onPause() {
super.onPause(); super.onPause();
MainApp.bus().unregister(this); disposable.clear();
} }
@Override @Override
@ -239,7 +254,7 @@ public class TDDStatsActivity extends NoSplashActivity {
statsMessage.setText(MainApp.gs(R.string.danar_stats_warning_Message)); statsMessage.setText(MainApp.gs(R.string.danar_stats_warning_Message));
} }
}); });
ConfigBuilderPlugin.getPlugin().getCommandQueue().loadTDDs( new Callback() { ConfigBuilderPlugin.getPlugin().getCommandQueue().loadTDDs(new Callback() {
@Override @Override
public void run() { public void run() {
loadDataFromDB(); loadDataFromDB();
@ -399,7 +414,7 @@ public class TDDStatsActivity extends NoSplashActivity {
//cumulative TDDs //cumulative TDDs
for (TDD record : historyList) { for (TDD record : historyList) {
if(!historyList.isEmpty() && df.format(new Date(record.date)).equals(df.format(new Date()))) { if (!historyList.isEmpty() && df.format(new Date(record.date)).equals(df.format(new Date()))) {
//Today should not be included //Today should not be included
continue; continue;
} }
@ -448,7 +463,7 @@ public class TDDStatsActivity extends NoSplashActivity {
tl.setBackgroundColor(Color.TRANSPARENT); tl.setBackgroundColor(Color.TRANSPARENT);
} }
if(!historyList.isEmpty() && df.format(new Date(historyList.get(0).date)).equals(df.format(new Date()))) { if (!historyList.isEmpty() && df.format(new Date(historyList.get(0).date)).equals(df.format(new Date()))) {
//Today should not be included //Today should not be included
historyList.remove(0); historyList.remove(0);
} }
@ -519,42 +534,17 @@ public class TDDStatsActivity extends NoSplashActivity {
} }
} }
@Subscribe
public void onStatusEvent(final EventDanaRSyncStatus s) {
log.debug("EventDanaRSyncStatus: " + s.message);
runOnUiThread(
new Runnable() {
@Override
public void run() {
statusView.setText(s.message);
}
});
}
@Subscribe
public void onStatusEvent(final EventPumpStatusChanged c) {
runOnUiThread(
new Runnable() {
@Override
public void run() {
statusView.setText(c.textStatus());
}
}
);
}
public static boolean isOldData(List<TDD> historyList) { public static boolean isOldData(List<TDD> historyList) {
Object activePump = ConfigBuilderPlugin.getPlugin().getActivePump(); Object activePump = ConfigBuilderPlugin.getPlugin().getActivePump();
PumpInterface dana = MainApp.getSpecificPlugin(DanaRPlugin.class); PumpInterface dana = DanaRPlugin.getPlugin();
PumpInterface danaRS = MainApp.getSpecificPlugin(DanaRSPlugin.class); PumpInterface danaRS = DanaRSPlugin.getPlugin();
PumpInterface danaV2 = MainApp.getSpecificPlugin(DanaRv2Plugin.class); PumpInterface danaV2 = DanaRv2Plugin.getPlugin();
PumpInterface danaKorean = MainApp.getSpecificPlugin(DanaRKoreanPlugin.class); PumpInterface danaKorean = DanaRKoreanPlugin.getPlugin();
PumpInterface insight = MainApp.getSpecificPlugin(LocalInsightPlugin.class); PumpInterface insight = LocalInsightPlugin.getPlugin();
boolean startsYesterday = activePump == dana || activePump == danaRS || activePump == danaV2 || activePump == danaKorean || activePump == insight; boolean startsYesterday = activePump == dana || activePump == danaRS || activePump == danaV2 || activePump == danaKorean || activePump == insight;
DateFormat df = new SimpleDateFormat("dd.MM."); DateFormat df = new SimpleDateFormat("dd.MM.");
return (historyList.size() < 3 || !(df.format(new Date(historyList.get(0).date)).equals(df.format(new Date(System.currentTimeMillis() - (startsYesterday?1000 * 60 * 60 * 24:0)))))); return (historyList.size() < 3 || !(df.format(new Date(historyList.get(0).date)).equals(df.format(new Date(System.currentTimeMillis() - (startsYesterday ? 1000 * 60 * 60 * 24 : 0))))));
} }
} }

View file

@ -100,8 +100,8 @@ public class CareportalEvent implements DataPointWithLabelInterface, Interval {
String hours = " " + MainApp.gs(R.string.hours) + " "; String hours = " " + MainApp.gs(R.string.hours) + " ";
if (useShortText) { if (useShortText) {
days = "d"; days = MainApp.gs(R.string.shortday);
hours = "h"; hours = MainApp.gs(R.string.shorthour);
} }
return diff.get(TimeUnit.DAYS) + days + diff.get(TimeUnit.HOURS) + hours; return diff.get(TimeUnit.DAYS) + days + diff.get(TimeUnit.HOURS) + hours;

View file

@ -243,7 +243,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
new java.util.TimerTask() { new java.util.TimerTask() {
@Override @Override
public void run() { public void run() {
MainApp.bus().post(new EventRefreshOverview("resetDatabases")); RxBus.INSTANCE.send(new EventRefreshOverview("resetDatabases"));
} }
}, },
3000 3000
@ -412,7 +412,6 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public void run() { public void run() {
if (L.isEnabled(L.DATABASE)) if (L.isEnabled(L.DATABASE))
log.debug("Firing EventNewBg"); log.debug("Firing EventNewBg");
MainApp.bus().post(new EventNewBG(bgReading));
RxBus.INSTANCE.send(new EventNewBG(bgReading)); RxBus.INSTANCE.send(new EventNewBG(bgReading));
scheduledBgPost = null; scheduledBgPost = null;
} }
@ -738,7 +737,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public void run() { public void run() {
if (L.isEnabled(L.DATABASE)) if (L.isEnabled(L.DATABASE))
log.debug("Firing EventTempTargetChange"); log.debug("Firing EventTempTargetChange");
MainApp.bus().post(new EventTempTargetChange()); RxBus.INSTANCE.send(new EventTempTargetChange());
scheduledTemTargetPost = null; scheduledTemTargetPost = null;
} }
} }
@ -1035,10 +1034,10 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public void run() { public void run() {
if (L.isEnabled(L.DATABASE)) if (L.isEnabled(L.DATABASE))
log.debug("Firing EventTempBasalChange"); log.debug("Firing EventTempBasalChange");
MainApp.bus().post(new EventReloadTempBasalData()); RxBus.INSTANCE.send(new EventReloadTempBasalData());
MainApp.bus().post(new EventTempBasalChange()); RxBus.INSTANCE.send(new EventTempBasalChange());
if (earliestDataChange != null) if (earliestDataChange != null)
MainApp.bus().post(new EventNewHistoryData(earliestDataChange)); RxBus.INSTANCE.send(new EventNewHistoryData(earliestDataChange));
earliestDataChange = null; earliestDataChange = null;
scheduledTemBasalsPost = null; scheduledTemBasalsPost = null;
} }
@ -1371,9 +1370,9 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public void run() { public void run() {
if (L.isEnabled(L.DATABASE)) if (L.isEnabled(L.DATABASE))
log.debug("Firing EventExtendedBolusChange"); log.debug("Firing EventExtendedBolusChange");
MainApp.bus().post(new EventReloadTreatmentData(new EventExtendedBolusChange())); RxBus.INSTANCE.send(new EventReloadTreatmentData(new EventExtendedBolusChange()));
if (earliestDataChange != null) if (earliestDataChange != null)
MainApp.bus().post(new EventNewHistoryData(earliestDataChange)); RxBus.INSTANCE.send(new EventNewHistoryData(earliestDataChange));
earliestDataChange = null; earliestDataChange = null;
scheduledExtendedBolusPost = null; scheduledExtendedBolusPost = null;
} }
@ -1577,7 +1576,7 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public void run() { public void run() {
if (L.isEnabled(L.DATABASE)) if (L.isEnabled(L.DATABASE))
log.debug("Firing scheduleCareportalEventChange"); log.debug("Firing scheduleCareportalEventChange");
MainApp.bus().post(new EventCareportalEventChange()); RxBus.INSTANCE.send(new EventCareportalEventChange());
scheduledCareportalEventPost = null; scheduledCareportalEventPost = null;
} }
} }
@ -1720,8 +1719,8 @@ public class DatabaseHelper extends OrmLiteSqliteOpenHelper {
public void run() { public void run() {
if (L.isEnabled(L.DATABASE)) if (L.isEnabled(L.DATABASE))
log.debug("Firing EventProfileNeedsUpdate"); log.debug("Firing EventProfileNeedsUpdate");
MainApp.bus().post(new EventReloadProfileSwitchData()); RxBus.INSTANCE.send(new EventReloadProfileSwitchData());
MainApp.bus().post(new EventProfileNeedsUpdate()); RxBus.INSTANCE.send(new EventProfileNeedsUpdate());
scheduledProfileSwitchEventPost = null; scheduledProfileSwitchEventPost = null;
} }
} }

View file

@ -1,16 +0,0 @@
package info.nightscout.androidaps.events;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
/** Base class for all events posted on the event bus. */
public abstract class Event {
static {
ReflectionToStringBuilder.setDefaultStyle(ToStringStyle.SHORT_PREFIX_STYLE);
}
@Override
public String toString() {
return ReflectionToStringBuilder.toString(this);
}
}

View file

@ -0,0 +1,18 @@
package info.nightscout.androidaps.events
import org.apache.commons.lang3.builder.ReflectionToStringBuilder
import org.apache.commons.lang3.builder.ToStringStyle
/** Base class for all events posted on the event bus. */
abstract class Event {
override fun toString(): String {
return ReflectionToStringBuilder.toString(this)
}
companion object {
init {
ReflectionToStringBuilder.setDefaultStyle(ToStringStyle.SHORT_PREFIX_STYLE)
}
}
}

View file

@ -1,5 +0,0 @@
package info.nightscout.androidaps.events;
/** Base class for events to update the UI, mostly a specific tab. */
public class EventAcceptOpenLoopChange extends Event {
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventAcceptOpenLoopChange : Event()

View file

@ -1,7 +0,0 @@
package info.nightscout.androidaps.events;
/**
* Created by mike on 07.07.2016.
*/
public class EventAppExit extends Event {
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventAppExit : Event()

View file

@ -1,8 +0,0 @@
package info.nightscout.androidaps.events;
/**
* Created by mike on 23.01.2018.
*/
public class EventAppInitialized extends Event {
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventAppInitialized : Event()

View file

@ -1,21 +0,0 @@
package info.nightscout.androidaps.events;
/**
* Created by adrian on 07/02/17.
*/
public class EventBolusRequested extends Event {
private double amount;
public EventBolusRequested (double amount){
this.amount = amount;
}
public double getAmount() {
return amount;
}
public void setAmount(double amount) {
this.amount = amount;
}
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventBolusRequested(var amount: Double) : Event()

View file

@ -1,8 +0,0 @@
package info.nightscout.androidaps.events;
/**
* Created by mike on 25.05.2017.
*/
public class EventCareportalEventChange extends Event {
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventCareportalEventChange : Event()

View file

@ -1,8 +0,0 @@
package info.nightscout.androidaps.events;
/**
* Created by mike on 17.02.2017.
*/
public class EventConfigBuilderChange extends Event {
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventConfigBuilderChange : Event()

View file

@ -1,4 +0,0 @@
package info.nightscout.androidaps.events;
public class EventCustomActionsChanged extends Event {
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventCustomActionsChanged : Event()

View file

@ -1,8 +0,0 @@
package info.nightscout.androidaps.events;
/**
* Created by mike on 13.02.2018.
*/
public class EventCustomCalculationFinished extends Event {
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventCustomCalculationFinished : Event()

View file

@ -1,8 +0,0 @@
package info.nightscout.androidaps.events;
/**
* Created by mike on 15.05.2017.
*/
public class EventExtendedBolusChange extends Event {
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventExtendedBolusChange : EventLoop()

View file

@ -1,36 +0,0 @@
package info.nightscout.androidaps.events;
/**
* Created by jamorham on 07/02/2018.
*
* Event to indicate that an app feature is being used, for example bolus wizard being opened
*
* The purpose this has been created for is to enable opportunistic connection to the pump
* so that it is already connected before the user wishes to enact a pump function
*
*/
public class EventFeatureRunning extends Event {
private Feature feature = Feature.UNKNOWN;
public EventFeatureRunning() {
}
public EventFeatureRunning(Feature feature) {
this.feature = feature;
}
public Feature getFeature() {
return feature;
}
public enum Feature {
UNKNOWN,
MAIN,
WIZARD,
JUST_ADD_MORE_HERE
}
}

View file

@ -1,8 +0,0 @@
package info.nightscout.androidaps.events;
/**
* Created by mike on 20.09.2017.
*/
public class EventFoodDatabaseChanged extends Event {
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventFoodDatabaseChanged : Event()

View file

@ -1,8 +0,0 @@
package info.nightscout.androidaps.events;
/**
* Created by mike on 13.12.2016.
*/
public class EventInitializationChanged extends Event {
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventInitializationChanged : Event()

View file

@ -1,11 +0,0 @@
package info.nightscout.androidaps.events;
import android.location.Location;
public class EventLocationChange extends Event {
public Location location;
public EventLocationChange(Location location) {
this.location = location;
}
}

View file

@ -0,0 +1,5 @@
package info.nightscout.androidaps.events
import android.location.Location
class EventLocationChange(var location: Location) : Event()

View file

@ -1,5 +0,0 @@
package info.nightscout.androidaps.events;
/** Supeclass for all events concerned with input or output into or from the LoopPlugin. */
public abstract class EventLoop extends Event {
}

View file

@ -0,0 +1,4 @@
package info.nightscout.androidaps.events
/** Supeclass for all events concerned with input or output into or from the LoopPlugin. */
abstract class EventLoop : Event()

View file

@ -1,17 +0,0 @@
package info.nightscout.androidaps.events;
import info.nightscout.androidaps.utils.StringUtils;
public class EventNetworkChange extends Event {
public boolean mobileConnected = false;
public boolean wifiConnected = false;
public String ssid = "";
public boolean roaming = false;
public String getSsid() {
return StringUtils.removeSurroundingQuotes(ssid);
}
}

View file

@ -0,0 +1,16 @@
package info.nightscout.androidaps.events
import info.nightscout.androidaps.utils.StringUtils
class EventNetworkChange : Event() {
var mobileConnected = false
var wifiConnected = false
var ssid = ""
var roaming = false
fun connectedSsid(): String {
return StringUtils.removeSurroundingQuotes(ssid)
}
}

View file

@ -1,17 +0,0 @@
package info.nightscout.androidaps.events;
import androidx.annotation.Nullable;
import info.nightscout.androidaps.db.BgReading;
/**
* Created by mike on 05.06.2016.
*/
public class EventNewBG extends EventLoop {
@Nullable
public final BgReading bgReading;
public EventNewBG(BgReading bgReading) {
this.bgReading = bgReading;
}
}

View file

@ -0,0 +1,5 @@
package info.nightscout.androidaps.events
import info.nightscout.androidaps.db.BgReading
class EventNewBG(val bgReading: BgReading?) : EventLoop()

View file

@ -1,7 +0,0 @@
package info.nightscout.androidaps.events;
/**
* Created by mike on 04.06.2016.
*/
public class EventNewBasalProfile extends Event {
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventNewBasalProfile : Event()

View file

@ -1,35 +0,0 @@
package info.nightscout.androidaps.events;
import android.os.Bundle;
/**
* Event which is published with data fetched from NightScout specific for the
* Food-class.
*
* Payload is the from NS retrieved JSON-String which should be handled by all
* subscriber.
*/
public class EventNsFood extends Event {
public static final int ADD = 0;
public static final int UPDATE = 1;
public static final int REMOVE = 2;
private final int mode;
private final Bundle payload;
public EventNsFood(int mode, Bundle payload) {
this.mode = mode;
this.payload = payload;
}
public int getMode() {
return mode;
}
public Bundle getPayload() {
return payload;
}
}

View file

@ -0,0 +1,19 @@
package info.nightscout.androidaps.events
import android.os.Bundle
/**
* Event which is published with data fetched from NightScout specific for the
* Food-class.
*
* Payload is the from NS retrieved JSON-String which should be handled by all
* subscriber.
*/
class EventNsFood(val mode: Int, val payload: Bundle) : Event() {
companion object {
val ADD = 0
val UPDATE = 1
val REMOVE = 2
}
}

View file

@ -1,36 +0,0 @@
package info.nightscout.androidaps.events;
import org.json.JSONObject;
/**
* Event which is published with data fetched from NightScout specific for the
* Treatment-class.
* <p>
* Payload is the from NS retrieved JSON-String which should be handled by all
* subscriber.
*/
public class EventNsTreatment extends Event {
public static final int ADD = 0;
public static final int UPDATE = 1;
public static final int REMOVE = 2;
private final int mode;
private final JSONObject payload;
public EventNsTreatment(int mode, JSONObject payload) {
this.mode = mode;
this.payload = payload;
}
public int getMode() {
return mode;
}
public JSONObject getPayload() {
return payload;
}
}

View file

@ -0,0 +1,21 @@
package info.nightscout.androidaps.events
import org.json.JSONObject
/**
* Event which is published with data fetched from NightScout specific for the
* Treatment-class.
*
*
* Payload is the from NS retrieved JSON-String which should be handled by all
* subscriber.
*/
class EventNsTreatment(val mode: Int, val payload: JSONObject) : Event() {
companion object {
val ADD = 0
val UPDATE = 1
val REMOVE = 2
}
}

View file

@ -1,25 +0,0 @@
package info.nightscout.androidaps.events;
import info.nightscout.androidaps.MainApp;
/**
* Created by mike on 19.06.2016.
*/
public class EventPreferenceChange extends Event {
public String changedKey;
public EventPreferenceChange(String key) {
changedKey = key;
}
public EventPreferenceChange(int resourceID) {
changedKey = MainApp.gs(resourceID);
}
public boolean isChanged(int id) {
return changedKey.equals(MainApp.gs(id));
}
public boolean isChanged(String id) {
return changedKey.equals(id);
}
}

View file

@ -0,0 +1,19 @@
package info.nightscout.androidaps.events
import info.nightscout.androidaps.MainApp
class EventPreferenceChange : Event {
private var changedKey: String? = null
constructor(key: String) {
changedKey = key
}
constructor(resourceID: Int) {
changedKey = MainApp.gs(resourceID)
}
fun isChanged(id: Int): Boolean {
return changedKey == MainApp.gs(id)
}
}

View file

@ -1,8 +0,0 @@
package info.nightscout.androidaps.events;
/**
* Created by mike on 02.06.2017.
*/
public class EventProfileNeedsUpdate extends Event {
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventProfileNeedsUpdate : Event()

View file

@ -1,4 +0,0 @@
package info.nightscout.androidaps.events;
public class EventProfileStoreChanged extends Event {
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventProfileStoreChanged : Event()

View file

@ -1,63 +0,0 @@
package info.nightscout.androidaps.events;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
/**
* Created by mike on 19.02.2017.
*/
public class EventPumpStatusChanged extends Event {
public static final int CONNECTING = 0;
public static final int CONNECTED = 1;
public static final int HANDSHAKING = 2;
public static final int PERFORMING = 3;
public static final int DISCONNECTING = 4;
public static final int DISCONNECTED = 5;
public int sStatus = DISCONNECTED;
public int sSecondsElapsed = 0;
public String sPerfomingAction = "";
public static String error = "";
public EventPumpStatusChanged(int status) {
sStatus = status;
sSecondsElapsed = 0;
error = "";
}
public EventPumpStatusChanged(int status, int secondsElapsed) {
sStatus = status;
sSecondsElapsed = secondsElapsed;
error = "";
}
public EventPumpStatusChanged(int status, String error) {
sStatus = status;
sSecondsElapsed = 0;
this.error = error;
}
public EventPumpStatusChanged(String action) {
sStatus = PERFORMING;
sSecondsElapsed = 0;
sPerfomingAction = action;
}
public String textStatus() {
if (sStatus == CONNECTING)
return String.format(MainApp.gs(R.string.danar_history_connectingfor), sSecondsElapsed);
else if (sStatus == HANDSHAKING)
return MainApp.gs(R.string.handshaking);
else if (sStatus == CONNECTED)
return MainApp.gs(R.string.connected);
else if (sStatus == PERFORMING)
return sPerfomingAction;
else if (sStatus == DISCONNECTING)
return MainApp.gs(R.string.disconnecting);
else if (sStatus == DISCONNECTED)
return "";
return "";
}
}

View file

@ -0,0 +1,62 @@
package info.nightscout.androidaps.events
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
class EventPumpStatusChanged : EventStatus {
enum class Status {
CONNECTING,
CONNECTED,
HANDSHAKING,
PERFORMING,
DISCONNECTING,
DISCONNECTED
}
var sStatus: Status = Status.DISCONNECTED
var sSecondsElapsed = 0
var sPerfomingAction = ""
var error = ""
constructor(status: Status) {
sStatus = status
sSecondsElapsed = 0
error = ""
}
constructor(status: Status, secondsElapsed: Int) {
sStatus = status
sSecondsElapsed = secondsElapsed
error = ""
}
constructor(status: Status, error: String) {
sStatus = status
sSecondsElapsed = 0
this.error = error
}
constructor(action: String) {
sStatus = Status.PERFORMING
sSecondsElapsed = 0
sPerfomingAction = action
}
// status for startup wizard
override fun getStatus(): String {
if (sStatus == Status.CONNECTING)
return String.format(MainApp.gs(R.string.danar_history_connectingfor), sSecondsElapsed)
else if (sStatus == Status.HANDSHAKING)
return MainApp.gs(R.string.handshaking)
else if (sStatus == Status.CONNECTED)
return MainApp.gs(R.string.connected)
else if (sStatus == Status.PERFORMING)
return sPerfomingAction
else if (sStatus == Status.DISCONNECTING)
return MainApp.gs(R.string.disconnecting)
else if (sStatus == Status.DISCONNECTED)
return ""
return ""
}
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventRebuildTabs @JvmOverloads constructor(var recreate: Boolean = false) : Event()

View file

@ -1,14 +0,0 @@
package info.nightscout.androidaps.events;
/**
* Created by mike on 13.06.2016.
*/
public class EventRefreshGui extends Event {
public boolean recreate = false;
public EventRefreshGui(boolean recreate) {
this.recreate = recreate;
}
public EventRefreshGui(){
this(false);
}
}

View file

@ -1,13 +0,0 @@
package info.nightscout.androidaps.events;
/**
* Created by mike on 16.06.2017.
*/
public class EventRefreshOverview extends Event {
public String from;
public EventRefreshOverview(String from) {
this.from = from;
}
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventRefreshOverview(var from: String) : Event()

View file

@ -1,8 +0,0 @@
package info.nightscout.androidaps.events;
/**
* Created by mike on 12.06.2017.
*/
public class EventReloadProfileSwitchData extends Event {
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventReloadProfileSwitchData : Event()

View file

@ -1,8 +0,0 @@
package info.nightscout.androidaps.events;
/**
* Created by mike on 29.05.2017.
*/
public class EventReloadTempBasalData extends Event {
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventReloadTempBasalData : Event()

View file

@ -1,13 +0,0 @@
package info.nightscout.androidaps.events;
/**
* Created by mike on 29.05.2017.
*/
public class EventReloadTreatmentData extends Event {
public Object next;
public EventReloadTreatmentData(Object next) {
this.next = next;
}
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventReloadTreatmentData(var next: Event) : Event()

View file

@ -0,0 +1,6 @@
package info.nightscout.androidaps.events
// pass string to startup wizard
abstract class EventStatus :Event() {
abstract fun getStatus() : String
}

View file

@ -1,7 +0,0 @@
package info.nightscout.androidaps.events;
/**
* Created by mike on 05.06.2016.
*/
public class EventTempBasalChange extends EventLoop {
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventTempBasalChange : EventLoop()

View file

@ -1,8 +0,0 @@
package info.nightscout.androidaps.events;
/**
* Created by mike on 13.01.2017.
*/
public class EventTempTargetChange extends Event {
}

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.events
class EventTempTargetChange : Event()

View file

@ -1,17 +0,0 @@
package info.nightscout.androidaps.events;
import androidx.annotation.Nullable;
import info.nightscout.androidaps.plugins.treatments.Treatment;
/**
* Created by mike on 04.06.2016.
*/
public class EventTreatmentChange extends EventLoop {
@Nullable
public final Treatment treatment;
public EventTreatmentChange(Treatment treatment) {
this.treatment = treatment;
}
}

View file

@ -0,0 +1,5 @@
package info.nightscout.androidaps.events
import info.nightscout.androidaps.plugins.treatments.Treatment
class EventTreatmentChange(val treatment: Treatment?) : EventLoop()

View file

@ -1,5 +0,0 @@
package info.nightscout.androidaps.events;
/** Base class for events to update the UI, mostly a specific tab. */
public abstract class EventUpdateGui extends Event {
}

View file

@ -0,0 +1,4 @@
package info.nightscout.androidaps.events
/** Base class for events to update the UI, mostly a specific tab. */
abstract class EventUpdateGui : Event()

View file

@ -1,24 +1,26 @@
package info.nightscout.androidaps.interfaces; package info.nightscout.androidaps.interfaces;
import android.os.SystemClock; import android.os.SystemClock;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import info.nightscout.androidaps.R; import org.jetbrains.annotations.NotNull;
import info.nightscout.androidaps.events.EventConfigBuilderChange;
import info.nightscout.androidaps.events.EventRefreshGui;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.configBuilder.EventConfigBuilderUpdateGui;
import info.nightscout.androidaps.utils.SP;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.events.EventConfigBuilderChange;
import info.nightscout.androidaps.events.EventRebuildTabs;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderFragment; import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.EventConfigBuilderUpdateGui;
import info.nightscout.androidaps.queue.CommandQueue; import info.nightscout.androidaps.queue.CommandQueue;
import info.nightscout.androidaps.utils.SP;
/** /**
* Created by mike on 09.06.2016. * Created by mike on 09.06.2016.
@ -81,8 +83,8 @@ public abstract class PluginBase {
setFragmentVisible(type, enabled); setFragmentVisible(type, enabled);
ConfigBuilderPlugin.getPlugin().processOnEnabledCategoryChanged(this, getType()); ConfigBuilderPlugin.getPlugin().processOnEnabledCategoryChanged(this, getType());
ConfigBuilderPlugin.getPlugin().storeSettings("CheckedCheckboxEnabled"); ConfigBuilderPlugin.getPlugin().storeSettings("CheckedCheckboxEnabled");
MainApp.bus().post(new EventRefreshGui()); RxBus.INSTANCE.send(new EventRebuildTabs());
MainApp.bus().post(new EventConfigBuilderChange()); RxBus.INSTANCE.send(new EventConfigBuilderChange());
RxBus.INSTANCE.send(new EventConfigBuilderUpdateGui()); RxBus.INSTANCE.send(new EventConfigBuilderUpdateGui());
ConfigBuilderPlugin.getPlugin().logPluginStatus(); ConfigBuilderPlugin.getPlugin().logPluginStatus();
} }
@ -216,4 +218,10 @@ public abstract class PluginBase {
protected void onStateChange(PluginType type, State oldState, State newState) { protected void onStateChange(PluginType type, State oldState, State newState) {
} }
public void preprocessPreferences(@NotNull final PreferenceFragment preferenceFragment) {
}
public void updatePreferenceSummary(@NotNull final Preference pref) {
}
} }

View file

@ -247,7 +247,7 @@ public class APSResult {
} }
} }
} catch (JSONException e) { } catch (JSONException e) {
e.printStackTrace(); log.error("Unhandled exception", e);
} }
return array; return array;
} }
@ -280,7 +280,7 @@ public class APSResult {
} }
} }
} catch (JSONException e) { } catch (JSONException e) {
e.printStackTrace(); log.error("Unhandled exception", e);
} }
return latest; return latest;

View file

@ -14,8 +14,6 @@ import android.os.SystemClock;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import com.squareup.otto.Subscribe;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -52,6 +50,7 @@ import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions; import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.nsclient.NSUpload; import info.nightscout.androidaps.plugins.general.nsclient.NSUpload;
import info.nightscout.androidaps.plugins.general.overview.dialogs.ErrorHelperActivity;
import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler; import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler;
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.events.EventAutosensCalculationFinished;
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin; import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin;
@ -62,12 +61,15 @@ import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.utils.T; import info.nightscout.androidaps.utils.T;
import info.nightscout.androidaps.utils.ToastUtils; import info.nightscout.androidaps.utils.ToastUtils;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
/** /**
* Created by mike on 05.08.2016. * Created by mike on 05.08.2016.
*/ */
public class LoopPlugin extends PluginBase { public class LoopPlugin extends PluginBase {
private static Logger log = LoggerFactory.getLogger(L.APS); private static Logger log = LoggerFactory.getLogger(L.APS);
private CompositeDisposable disposable = new CompositeDisposable();
private static final String CHANNEL_ID = "AndroidAPS-Openloop"; private static final String CHANNEL_ID = "AndroidAPS-Openloop";
@ -116,9 +118,39 @@ public class LoopPlugin extends PluginBase {
@Override @Override
protected void onStart() { protected void onStart() {
MainApp.bus().register(this);
createNotificationChannel(); createNotificationChannel();
super.onStart(); super.onStart();
disposable.add(RxBus.INSTANCE
.toObservable(EventTempTargetChange.class)
.observeOn(Schedulers.io())
.subscribe(event -> {
invoke("EventTempTargetChange", true);
}, FabricPrivacy::logException)
);
/**
* This method is triggered once autosens calculation has completed, so the LoopPlugin
* has current data to work with. However, autosens calculation can be triggered by multiple
* sources and currently only a new BG should trigger a loop run. Hence we return early if
* the event causing the calculation is not EventNewBg.
* <p>
*/
disposable.add(RxBus.INSTANCE
.toObservable(EventAutosensCalculationFinished.class)
.observeOn(Schedulers.io())
.subscribe(event -> {
// Autosens calculation not triggered by a new BG
if (!(event.getCause() instanceof EventNewBG)) return;
BgReading bgReading = DatabaseHelper.actualBg();
// BG outdated
if (bgReading == null) return;
// already looped with that value
if (bgReading.date <= lastBgTriggeredRun) return;
lastBgTriggeredRun = bgReading.date;
invoke("AutosenseCalculation for " + bgReading, true);
}, FabricPrivacy::logException)
);
} }
private void createNotificationChannel() { private void createNotificationChannel() {
@ -135,8 +167,8 @@ public class LoopPlugin extends PluginBase {
@Override @Override
protected void onStop() { protected void onStop() {
disposable.clear();
super.onStop(); super.onStop();
MainApp.bus().unregister(this);
} }
@Override @Override
@ -145,43 +177,10 @@ public class LoopPlugin extends PluginBase {
return pump == null || pump.getPumpDescription().isTempBasalCapable; return pump == null || pump.getPumpDescription().isTempBasalCapable;
} }
/**
* This method is triggered once autosens calculation has completed, so the LoopPlugin
* has current data to work with. However, autosens calculation can be triggered by multiple
* sources and currently only a new BG should trigger a loop run. Hence we return early if
* the event causing the calculation is not EventNewBg.
* <p>
*/
@Subscribe
public void onStatusEvent(final EventAutosensCalculationFinished ev) {
if (!(ev.getCause() instanceof EventNewBG)) {
// Autosens calculation not triggered by a new BG
return;
}
BgReading bgReading = DatabaseHelper.actualBg();
if (bgReading == null) {
// BG outdated
return;
}
if (bgReading.date <= lastBgTriggeredRun) {
// already looped with that value
return;
}
lastBgTriggeredRun = bgReading.date;
invoke("AutosenseCalculation for " + bgReading, true);
}
public long suspendedTo() { public long suspendedTo() {
return loopSuspendedTill; return loopSuspendedTill;
} }
@Subscribe
public void onStatusEvent(final EventTempTargetChange ev) {
new Thread(() -> invoke("EventTempTargetChange", true)).start();
}
public void suspendTo(long endTime) { public void suspendTo(long endTime) {
loopSuspendedTill = endTime; loopSuspendedTill = endTime;
isSuperBolus = false; isSuperBolus = false;
@ -439,7 +438,7 @@ public class LoopPlugin extends PluginBase {
(NotificationManager) MainApp.instance().getSystemService(Context.NOTIFICATION_SERVICE); (NotificationManager) MainApp.instance().getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on. // mId allows you to update the notification later on.
mNotificationManager.notify(Constants.notificationID, builder.build()); mNotificationManager.notify(Constants.notificationID, builder.build());
MainApp.bus().post(new EventNewOpenLoopNotification()); RxBus.INSTANCE.send(new EventNewOpenLoopNotification());
// Send to Wear // Send to Wear
ActionStringHandler.handleInitiate("changeRequest"); ActionStringHandler.handleInitiate("changeRequest");
@ -472,7 +471,7 @@ public class LoopPlugin extends PluginBase {
NSUpload.uploadDeviceStatus(); NSUpload.uploadDeviceStatus();
SP.incInt(R.string.key_ObjectivesmanualEnacts); SP.incInt(R.string.key_ObjectivesmanualEnacts);
} }
MainApp.bus().post(new EventAcceptOpenLoopChange()); RxBus.INSTANCE.send(new EventAcceptOpenLoopChange());
} }
}); });
FabricPrivacy.getInstance().logCustom("AcceptTemp"); FabricPrivacy.getInstance().logCustom("AcceptTemp");
@ -647,7 +646,12 @@ public class LoopPlugin extends PluginBase {
@Override @Override
public void run() { public void run() {
if (!result.success) { if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror)); Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.tempbasaldeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
} }
} }
}); });
@ -656,7 +660,12 @@ public class LoopPlugin extends PluginBase {
@Override @Override
public void run() { public void run() {
if (!result.success) { if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror)); Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.tempbasaldeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
} }
} }
}); });
@ -667,7 +676,12 @@ public class LoopPlugin extends PluginBase {
@Override @Override
public void run() { public void run() {
if (!result.success) { if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.extendedbolusdeliveryerror)); Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.extendedbolusdeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
} }
} }
}); });
@ -681,7 +695,12 @@ public class LoopPlugin extends PluginBase {
@Override @Override
public void run() { public void run() {
if (!result.success) { if (!result.success) {
ToastUtils.showToastInUiThread(MainApp.instance().getApplicationContext(), MainApp.gs(R.string.tempbasaldeliveryerror)); Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
i.putExtra("soundid", R.raw.boluserror);
i.putExtra("status", result.comment);
i.putExtra("title", MainApp.gs(R.string.tempbasaldeliveryerror));
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
MainApp.instance().startActivity(i);
} }
} }
}); });

View file

@ -1,9 +0,0 @@
package info.nightscout.androidaps.plugins.aps.loop.events;
import info.nightscout.androidaps.events.Event;
/**
* Created by mike on 07.08.2016.
*/
public class EventNewOpenLoopNotification extends Event {
}

View file

@ -0,0 +1,5 @@
package info.nightscout.androidaps.plugins.aps.loop.events
import info.nightscout.androidaps.events.Event
class EventNewOpenLoopNotification : Event()

View file

@ -164,7 +164,7 @@ public class OpenAPSAMAPlugin extends PluginBase implements APSInterface {
return; return;
if (!HardLimits.checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF)) if (!HardLimits.checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
return; return;
if (!HardLimits.checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal())) if (!HardLimits.checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.02, HardLimits.maxBasal()))
return; return;
if (!HardLimits.checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal())) if (!HardLimits.checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal()))
return; return;

View file

@ -162,7 +162,7 @@ public class OpenAPSMAPlugin extends PluginBase implements APSInterface {
return; return;
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF)) if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
return; return;
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal())) if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.02, HardLimits.maxBasal()))
return; return;
if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal())) if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal()))
return; return;

View file

@ -170,7 +170,7 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, Constr
return; return;
if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF)) if (!checkOnlyHardLimits(Profile.toMgdl(profile.getIsf(), units), "sens", HardLimits.MINISF, HardLimits.MAXISF))
return; return;
if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.05, HardLimits.maxBasal())) if (!checkOnlyHardLimits(profile.getMaxDailyBasal(), "max_daily_basal", 0.02, HardLimits.maxBasal()))
return; return;
if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal())) if (!checkOnlyHardLimits(pump.getBaseBasalRate(), "current_basal", 0.01, HardLimits.maxBasal()))
return; return;

View file

@ -1,22 +0,0 @@
package info.nightscout.androidaps.plugins.common;
import androidx.fragment.app.Fragment;
import info.nightscout.androidaps.MainApp;
abstract public class SubscriberFragment extends Fragment {
@Override
public void onPause() {
super.onPause();
MainApp.bus().unregister(this);
}
@Override
public void onResume() {
super.onResume();
MainApp.bus().register(this);
updateGUI();
}
protected abstract void updateGUI();
}

View file

@ -20,6 +20,7 @@ import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.interfaces.SensitivityInterface; import info.nightscout.androidaps.interfaces.SensitivityInterface;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.insulin.InsulinOrefRapidActingPlugin; import info.nightscout.androidaps.plugins.insulin.InsulinOrefRapidActingPlugin;
import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin; import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin;
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin; import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin;
@ -67,14 +68,12 @@ public class ConfigBuilderPlugin extends PluginBase {
@Override @Override
protected void onStart() { protected void onStart() {
MainApp.bus().register(this);
super.onStart(); super.onStart();
} }
@Override @Override
protected void onStop() { protected void onStop() {
super.onStop(); super.onStop();
MainApp.bus().unregister(this);
} }
@ -83,7 +82,7 @@ public class ConfigBuilderPlugin extends PluginBase {
upgradeSettings(); upgradeSettings();
loadSettings(); loadSettings();
setAlwaysEnabledPluginsEnabled(); setAlwaysEnabledPluginsEnabled();
MainApp.bus().post(new EventAppInitialized()); RxBus.INSTANCE.send(new EventAppInitialized());
} }
private void setAlwaysEnabledPluginsEnabled() { private void setAlwaysEnabledPluginsEnabled() {

View file

@ -3,12 +3,12 @@ package info.nightscout.androidaps.plugins.configBuilder
import android.content.Intent import android.content.Intent
import android.view.View import android.view.View
import android.widget.* import android.widget.*
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.PreferencesActivity import info.nightscout.androidaps.activities.PreferencesActivity
import info.nightscout.androidaps.events.EventRefreshGui import info.nightscout.androidaps.events.EventRebuildTabs
import info.nightscout.androidaps.interfaces.PluginBase import info.nightscout.androidaps.interfaces.PluginBase
import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.androidaps.interfaces.PluginType
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.utils.PasswordProtection import info.nightscout.androidaps.utils.PasswordProtection
class PluginViewHolder internal constructor(private val fragment: ConfigBuilderFragment, class PluginViewHolder internal constructor(private val fragment: ConfigBuilderFragment,
@ -34,7 +34,7 @@ class PluginViewHolder internal constructor(private val fragment: ConfigBuilderF
pluginVisibility.setOnClickListener { pluginVisibility.setOnClickListener {
plugin.setFragmentVisible(pluginType, pluginVisibility.isChecked) plugin.setFragmentVisible(pluginType, pluginVisibility.isChecked)
ConfigBuilderPlugin.getPlugin().storeSettings("CheckedCheckboxVisible") ConfigBuilderPlugin.getPlugin().storeSettings("CheckedCheckboxVisible")
MainApp.bus().post(EventRefreshGui()) RxBus.send(EventRebuildTabs())
ConfigBuilderPlugin.getPlugin().logPluginStatus() ConfigBuilderPlugin.getPlugin().logPluginStatus()
} }

View file

@ -2,10 +2,10 @@ package info.nightscout.androidaps.plugins.configBuilder;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.firebase.analytics.FirebaseAnalytics; import com.google.firebase.analytics.FirebaseAnalytics;
import com.squareup.otto.Subscribe;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -23,14 +23,19 @@ import info.nightscout.androidaps.events.EventProfileNeedsUpdate;
import info.nightscout.androidaps.interfaces.ProfileInterface; import info.nightscout.androidaps.interfaces.ProfileInterface;
import info.nightscout.androidaps.interfaces.TreatmentsInterface; import info.nightscout.androidaps.interfaces.TreatmentsInterface;
import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.logging.L;
import info.nightscout.androidaps.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.general.overview.dialogs.ErrorHelperActivity; import info.nightscout.androidaps.plugins.general.overview.dialogs.ErrorHelperActivity;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.queue.Callback; import info.nightscout.androidaps.queue.Callback;
import info.nightscout.androidaps.utils.DateUtil;
import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.FabricPrivacy;
import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.utils.SP;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.schedulers.Schedulers;
public class ProfileFunctions { public class ProfileFunctions {
private static Logger log = LoggerFactory.getLogger(L.PROFILE); private static Logger log = LoggerFactory.getLogger(L.PROFILE);
private CompositeDisposable disposable = new CompositeDisposable();
private static ProfileFunctions profileFunctions = null; private static ProfileFunctions profileFunctions = null;
@ -44,61 +49,69 @@ public class ProfileFunctions {
ProfileFunctions.getInstance(); // register to bus at start ProfileFunctions.getInstance(); // register to bus at start
} }
ProfileFunctions() { private ProfileFunctions() {
MainApp.bus().register(this); disposable.add(RxBus.INSTANCE
} .toObservable(EventProfileNeedsUpdate.class)
.observeOn(Schedulers.io())
@Subscribe .subscribe(event -> {
public void onProfileSwitch(EventProfileNeedsUpdate ignored) { if (L.isEnabled(L.PROFILE))
if (L.isEnabled(L.PROFILE)) log.debug("onProfileSwitch");
log.debug("onProfileSwitch"); ConfigBuilderPlugin.getPlugin().getCommandQueue().setProfile(getProfile(), new Callback() {
ConfigBuilderPlugin.getPlugin().getCommandQueue().setProfile(getProfile(), new Callback() { @Override
@Override public void run() {
public void run() { if (!result.success) {
if (!result.success) { Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class);
Intent i = new Intent(MainApp.instance(), ErrorHelperActivity.class); i.putExtra("soundid", R.raw.boluserror);
i.putExtra("soundid", R.raw.boluserror); i.putExtra("status", result.comment);
i.putExtra("status", result.comment); i.putExtra("title", MainApp.gs(R.string.failedupdatebasalprofile));
i.putExtra("title", MainApp.gs(R.string.failedupdatebasalprofile)); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); MainApp.instance().startActivity(i);
MainApp.instance().startActivity(i); }
} if (result.enacted)
if (result.enacted) RxBus.INSTANCE.send(new EventNewBasalProfile());
MainApp.bus().post(new EventNewBasalProfile()); }
} });
}); }, FabricPrivacy::logException)
);
} }
public String getProfileName() { public String getProfileName() {
return getProfileName(System.currentTimeMillis()); return getProfileName(System.currentTimeMillis(), true, false);
} }
public String getProfileName(boolean customized) { public String getProfileName(boolean customized) {
return getProfileName(System.currentTimeMillis(), customized); return getProfileName(System.currentTimeMillis(), customized, false);
} }
public String getProfileName(long time) { public String getProfileNameWithDuration() {
return getProfileName(time, true); return getProfileName(System.currentTimeMillis(), true, true);
} }
public String getProfileName(long time, boolean customized) { public String getProfileName(long time, boolean customized, boolean showRemainingTime) {
String profileName = MainApp.gs(R.string.noprofileselected);
TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin(); TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin();
ProfileInterface activeProfile = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface(); ProfileInterface activeProfile = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface();
ProfileSwitch profileSwitch = activeTreatments.getProfileSwitchFromHistory(time); ProfileSwitch profileSwitch = activeTreatments.getProfileSwitchFromHistory(time);
if (profileSwitch != null) { if (profileSwitch != null) {
if (profileSwitch.profileJson != null) { if (profileSwitch.profileJson != null) {
return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName; profileName = customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName;
} else { } else {
ProfileStore profileStore = activeProfile.getProfile(); ProfileStore profileStore = activeProfile.getProfile();
if (profileStore != null) { if (profileStore != null) {
Profile profile = profileStore.getSpecificProfile(profileSwitch.profileName); Profile profile = profileStore.getSpecificProfile(profileSwitch.profileName);
if (profile != null) if (profile != null)
return profileSwitch.profileName; profileName = profileSwitch.profileName;
} }
} }
if (showRemainingTime && profileSwitch.durationInMinutes != 0) {
profileName += DateUtil.untilString(profileSwitch.originalEnd());
}
return profileName;
} }
return MainApp.gs(R.string.noprofileselected); return profileName;
} }
public boolean isProfileValid(String from) { public boolean isProfileValid(String from) {
@ -171,7 +184,7 @@ public class ProfileFunctions {
profileSwitch = new ProfileSwitch(); profileSwitch = new ProfileSwitch();
profileSwitch.date = System.currentTimeMillis(); profileSwitch.date = System.currentTimeMillis();
profileSwitch.source = Source.USER; profileSwitch.source = Source.USER;
profileSwitch.profileName = getInstance().getProfileName(System.currentTimeMillis(), false); profileSwitch.profileName = getInstance().getProfileName(System.currentTimeMillis(), false, false);
profileSwitch.profileJson = getInstance().getProfile().getData().toString(); profileSwitch.profileJson = getInstance().getProfile().getData().toString();
profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getClass().getName(); profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getClass().getName();
profileSwitch.durationInMinutes = duration; profileSwitch.durationInMinutes = duration;

View file

@ -22,7 +22,7 @@ import info.nightscout.androidaps.plugins.general.overview.notifications.Notific
public class DstHelperPlugin extends PluginBase implements ConstraintsInterface { public class DstHelperPlugin extends PluginBase implements ConstraintsInterface {
public static final int DISABLE_TIMEFRAME_HOURS = -3; public static final int DISABLE_TIMEFRAME_HOURS = -3;
public static final int WARN_PRIOR_TIMEFRAME_HOURS = 24; public static final int WARN_PRIOR_TIMEFRAME_HOURS = 12;
private static Logger log = LoggerFactory.getLogger(L.CONSTRAINTS); private static Logger log = LoggerFactory.getLogger(L.CONSTRAINTS);
static DstHelperPlugin plugin = null; static DstHelperPlugin plugin = null;

View file

@ -51,7 +51,6 @@ class ObjectivesFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) { override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState) super.onViewCreated(view, savedInstanceState)
objectives_recyclerview.layoutManager = LinearLayoutManager(view.context) objectives_recyclerview.layoutManager = LinearLayoutManager(view.context)
objectives_recyclerview.adapter = objectivesAdapter objectives_recyclerview.adapter = objectivesAdapter
objectives_fake.setOnClickListener { updateGUI() } objectives_fake.setOnClickListener { updateGUI() }
@ -105,17 +104,14 @@ class ObjectivesFragment : Fragment() {
for (i in 0 until ObjectivesPlugin.objectives.size) { for (i in 0 until ObjectivesPlugin.objectives.size) {
val objective = ObjectivesPlugin.objectives[i] val objective = ObjectivesPlugin.objectives[i]
if (!objective.isStarted || !objective.isAccomplished) { if (!objective.isStarted || !objective.isAccomplished) {
val smoothScroller = object : LinearSmoothScroller(context!!) { context?.let {
override fun getVerticalSnapPreference(): Int { val smoothScroller = object : LinearSmoothScroller(it) {
return SNAP_TO_START override fun getVerticalSnapPreference(): Int = SNAP_TO_START
} override fun calculateTimeForScrolling(dx: Int): Int = super.calculateTimeForScrolling(dx) * 4
override fun calculateTimeForScrolling(dx: Int): Int {
return super.calculateTimeForScrolling(dx) * 4
} }
smoothScroller.targetPosition = i
objectives_recyclerview.layoutManager?.startSmoothScroll(smoothScroller)
} }
smoothScroller.targetPosition = i
objectives_recyclerview.layoutManager?.startSmoothScroll(smoothScroller)
break break
} }
} }
@ -208,49 +204,63 @@ class ObjectivesFragment : Fragment() {
holder.accomplished.setTextColor(-0x3e3e3f) holder.accomplished.setTextColor(-0x3e3e3f)
holder.verify.setOnClickListener { holder.verify.setOnClickListener {
holder.verify.visibility = View.INVISIBLE holder.verify.visibility = View.INVISIBLE
SntpClient.ntpTime(object : SntpClient.Callback() { NetworkChangeReceiver.grabNetworkStatus(context)
override fun run() { if (objectives_fake.isChecked) {
activity?.runOnUiThread { objective.accomplishedOn = DateUtil.now()
holder.verify.visibility = View.VISIBLE scrollToCurrentObjective()
log.debug("NTP time: $time System time: ${DateUtil.now()}") startUpdateTimer()
if (!networkConnected) { RxBus.send(EventObjectivesUpdateGui())
ToastUtils.showToastInUiThread(context, R.string.notconnected) } else
} else if (success) { SntpClient.ntpTime(object : SntpClient.Callback() {
if (objective.isCompleted(time)) { override fun run() {
objective.accomplishedOn = time activity?.runOnUiThread {
notifyDataSetChanged() holder.verify.visibility = View.VISIBLE
scrollToCurrentObjective() log.debug("NTP time: $time System time: ${DateUtil.now()}")
startUpdateTimer() if (!networkConnected) {
ToastUtils.showToastInUiThread(context, R.string.notconnected)
} else if (success) {
if (objective.isCompleted(time)) {
objective.accomplishedOn = time
scrollToCurrentObjective()
startUpdateTimer()
RxBus.send(EventObjectivesUpdateGui())
} else {
ToastUtils.showToastInUiThread(context, R.string.requirementnotmet)
}
} else { } else {
ToastUtils.showToastInUiThread(context, R.string.requirementnotmet) ToastUtils.showToastInUiThread(context, R.string.failedretrievetime)
} }
} else {
ToastUtils.showToastInUiThread(context, R.string.failedretrievetime)
} }
} }
} }, NetworkChangeReceiver.isConnected())
}, NetworkChangeReceiver.isConnected())
} }
holder.start.setOnClickListener { holder.start.setOnClickListener {
holder.start.visibility = View.INVISIBLE holder.start.visibility = View.INVISIBLE
SntpClient.ntpTime(object : SntpClient.Callback() { NetworkChangeReceiver.grabNetworkStatus(context)
override fun run() { if (objectives_fake.isChecked) {
activity?.runOnUiThread { objective.startedOn = DateUtil.now()
holder.start.visibility = View.VISIBLE scrollToCurrentObjective()
log.debug("NTP time: $time System time: ${DateUtil.now()}") startUpdateTimer()
if (!networkConnected) { RxBus.send(EventObjectivesUpdateGui())
ToastUtils.showToastInUiThread(context, R.string.notconnected) } else
} else if (success) { SntpClient.ntpTime(object : SntpClient.Callback() {
objective.startedOn = time override fun run() {
notifyDataSetChanged() activity?.runOnUiThread {
scrollToCurrentObjective() holder.start.visibility = View.VISIBLE
startUpdateTimer() log.debug("NTP time: $time System time: ${DateUtil.now()}")
} else { if (!networkConnected) {
ToastUtils.showToastInUiThread(context, R.string.failedretrievetime) ToastUtils.showToastInUiThread(context, R.string.notconnected)
} else if (success) {
objective.startedOn = time
scrollToCurrentObjective()
startUpdateTimer()
RxBus.send(EventObjectivesUpdateGui())
} else {
ToastUtils.showToastInUiThread(context, R.string.failedretrievetime)
}
} }
} }
} }, NetworkChangeReceiver.isConnected())
}, NetworkChangeReceiver.isConnected())
} }
holder.revert.setOnClickListener { holder.revert.setOnClickListener {
objective.accomplishedOn = 0 objective.accomplishedOn = 0
@ -259,8 +269,8 @@ class ObjectivesFragment : Fragment() {
val prevObj = ObjectivesPlugin.objectives[position - 1] val prevObj = ObjectivesPlugin.objectives[position - 1]
prevObj.accomplishedOn = 0 prevObj.accomplishedOn = 0
} }
notifyDataSetChanged()
scrollToCurrentObjective() scrollToCurrentObjective()
RxBus.send(EventObjectivesUpdateGui())
} }
if (objective.hasSpecialInput && !objective.isAccomplished && objective.isStarted) { if (objective.hasSpecialInput && !objective.isAccomplished && objective.isStarted) {
// generate random request code if none exists // generate random request code if none exists
@ -274,7 +284,7 @@ class ObjectivesFragment : Fragment() {
holder.enterButton.setOnClickListener { holder.enterButton.setOnClickListener {
val input = holder.input.text.toString() val input = holder.input.text.toString()
objective.specialAction(activity, input) objective.specialAction(activity, input)
notifyDataSetChanged() RxBus.send(EventObjectivesUpdateGui())
} }
} else { } else {
holder.enterButton.visibility = View.GONE holder.enterButton.visibility = View.GONE

View file

@ -21,8 +21,8 @@ import java.util.*
object ObjectivesPlugin : PluginBase(PluginDescription() object ObjectivesPlugin : PluginBase(PluginDescription()
.mainType(PluginType.CONSTRAINTS) .mainType(PluginType.CONSTRAINTS)
.fragmentClass(ObjectivesFragment::class.qualifiedName) .fragmentClass(ObjectivesFragment::class.qualifiedName)
.alwaysEnabled(!Config.NSCLIENT) .alwaysEnabled(Config.APS)
.showInList(!Config.NSCLIENT) .showInList(Config.APS)
.pluginName(R.string.objectives) .pluginName(R.string.objectives)
.shortName(R.string.objectives_shortname) .shortName(R.string.objectives_shortname)
.description(R.string.description_objectives)), ConstraintsInterface { .description(R.string.description_objectives)), ConstraintsInterface {
@ -105,7 +105,7 @@ object ObjectivesPlugin : PluginBase(PluginDescription()
val requestCode = SP.getString(R.string.key_objectives_request_code, "") val requestCode = SP.getString(R.string.key_objectives_request_code, "")
var url = SP.getString(R.string.key_nsclientinternal_url, "").toLowerCase() var url = SP.getString(R.string.key_nsclientinternal_url, "").toLowerCase()
if (!url.endsWith("\"")) url = "$url/" if (!url.endsWith("\"")) url = "$url/"
val hashNS = Hashing.sha1().hashString(url + BuildConfig.APPLICATION_ID + "/" + requestCode, Charsets.UTF_8).toString() @Suppress("DEPRECATION") val hashNS = Hashing.sha1().hashString(url + BuildConfig.APPLICATION_ID + "/" + requestCode, Charsets.UTF_8).toString()
if (request.equals(hashNS.substring(0, 10), ignoreCase = true)) { if (request.equals(hashNS.substring(0, 10), ignoreCase = true)) {
SP.putLong("Objectives_" + "openloop" + "_started", DateUtil.now()) SP.putLong("Objectives_" + "openloop" + "_started", DateUtil.now())
SP.putLong("Objectives_" + "openloop" + "_accomplished", DateUtil.now()) SP.putLong("Objectives_" + "openloop" + "_accomplished", DateUtil.now())

View file

@ -57,12 +57,11 @@ class ObjectivesExamDialog : DialogFragment() {
objectives_exam_question.setText(task.question) objectives_exam_question.setText(task.question)
// Options // Options
objectives_exam_options.removeAllViews() objectives_exam_options.removeAllViews()
for (o in task.options) { task.options.forEach {
val option: Option = o as Option; val cb = it.generate(context)
val cb = option.generate(context)
if (task.answered) { if (task.answered) {
cb.isEnabled = false cb.isEnabled = false
if (option.isCorrect) if (it.isCorrect)
cb.isChecked = true cb.isChecked = true
} }
objectives_exam_options.addView(cb) objectives_exam_options.addView(cb)

View file

@ -230,7 +230,7 @@ public abstract class Objective {
return question; return question;
} }
public List getOptions() { public List<Objective.Option> getOptions() {
return options; return options;
} }

View file

@ -37,6 +37,7 @@ public class Objective2 extends Objective {
); );
tasks.add(new ExamTask(R.string.pumpdisconnect_label, R.string.pumpdisconnect_label,"pumpdisconnect") tasks.add(new ExamTask(R.string.pumpdisconnect_label, R.string.pumpdisconnect_label,"pumpdisconnect")
.option(new Option(R.string.pumpdisconnect_letknow, true)) .option(new Option(R.string.pumpdisconnect_letknow, true))
.option(new Option(R.string.pumpdisconnect_suspend, false))
.option(new Option(R.string.pumpdisconnect_dontchnage, false)) .option(new Option(R.string.pumpdisconnect_dontchnage, false))
.hint(new Hint(R.string.pumpdisconnect_hint1)) .hint(new Hint(R.string.pumpdisconnect_hint1))
); );
@ -45,6 +46,7 @@ public class Objective2 extends Objective {
.option(new Option(R.string.objectives_storeelsewhere, true)) .option(new Option(R.string.objectives_storeelsewhere, true))
.option(new Option(R.string.objectives_doexportonstart, false)) .option(new Option(R.string.objectives_doexportonstart, false))
.option(new Option(R.string.objectives_doexportafterchange, true)) .option(new Option(R.string.objectives_doexportafterchange, true))
.option(new Option(R.string.objectives_doexportafterobjective, true))
.option(new Option(R.string.objectives_doexportafterfirtssettings, true)) .option(new Option(R.string.objectives_doexportafterfirtssettings, true))
.hint(new Hint(R.string.objectives_hint1)) .hint(new Hint(R.string.objectives_hint1))
.hint(new Hint(R.string.objectives_hint2)) .hint(new Hint(R.string.objectives_hint2))
@ -65,6 +67,7 @@ public class Objective2 extends Objective {
.option(new Option(R.string.exercise_switchprofileabove100, false)) .option(new Option(R.string.exercise_switchprofileabove100, false))
.option(new Option(R.string.exercise_stoploop, false)) .option(new Option(R.string.exercise_stoploop, false))
.option(new Option(R.string.exercise_doitbeforestart, true)) .option(new Option(R.string.exercise_doitbeforestart, true))
.option(new Option(R.string.exercise_afterstart, true))
.hint(new Hint(R.string.exercise_hint1)) .hint(new Hint(R.string.exercise_hint1))
); );
tasks.add(new ExamTask(R.string.suspendloop_label, R.string.suspendloop_doigetinsulin,"suspendloop") tasks.add(new ExamTask(R.string.suspendloop_label, R.string.suspendloop_doigetinsulin,"suspendloop")
@ -196,6 +199,11 @@ public class Objective2 extends Objective {
.hint(new Hint(R.string.profileswitchtime_hint1)) .hint(new Hint(R.string.profileswitchtime_hint1))
); );
tasks.add(new ExamTask(R.string.other_medication_label, R.string.other_medication_text,"otherMedicationWarning")
.option(new Option(R.string.yes, true))
.option(new Option(R.string.no, false))
);
for (Task task : tasks) for (Task task : tasks)
Collections.shuffle(((ExamTask)task).options); Collections.shuffle(((ExamTask)task).options);
} }

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.general.signatureVerifier; package info.nightscout.androidaps.plugins.constraints.signatureVerifier;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.Signature; import android.content.pm.Signature;
@ -42,23 +42,23 @@ import info.nightscout.androidaps.utils.SP;
* In case someone decides to leak a ready-to-use APK nonetheless, we can still disable it. * In case someone decides to leak a ready-to-use APK nonetheless, we can still disable it.
* Self-compiled APKs with privately held certificates cannot and will not be disabled. * Self-compiled APKs with privately held certificates cannot and will not be disabled.
*/ */
public class SignatureVerifier extends PluginBase implements ConstraintsInterface { public class SignatureVerifierPlugin extends PluginBase implements ConstraintsInterface {
private static final String REVOKED_CERTS_URL = "https://raw.githubusercontent.com/MilosKozak/AndroidAPS/master/app/src/main/assets/revoked_certs.txt"; private static final String REVOKED_CERTS_URL = "https://raw.githubusercontent.com/MilosKozak/AndroidAPS/master/app/src/main/assets/revoked_certs.txt";
private static final long UPDATE_INTERVAL = TimeUnit.DAYS.toMillis(1); private static final long UPDATE_INTERVAL = TimeUnit.DAYS.toMillis(1);
private static SignatureVerifier plugin = new SignatureVerifier(); private static SignatureVerifierPlugin plugin = new SignatureVerifierPlugin();
private Logger log = LoggerFactory.getLogger(L.CORE); private Logger log = LoggerFactory.getLogger(L.CORE);
private final Object $lock = new Object[0]; private final Object $lock = new Object[0];
private File revokedCertsFile; private File revokedCertsFile;
private List<byte[]> revokedCerts; private List<byte[]> revokedCerts;
public static SignatureVerifier getPlugin() { public static SignatureVerifierPlugin getPlugin() {
return plugin; return plugin;
} }
private SignatureVerifier() { private SignatureVerifierPlugin() {
super(new PluginDescription() super(new PluginDescription()
.mainType(PluginType.CONSTRAINTS) .mainType(PluginType.CONSTRAINTS)
.neverVisible(true) .neverVisible(true)
@ -124,14 +124,52 @@ public class SignatureVerifier extends PluginBase implements ConstraintsInterfac
} }
} }
} }
} catch (PackageManager.NameNotFoundException e) { } catch (PackageManager.NameNotFoundException | NoSuchAlgorithmException e) {
log.error("Error in SignatureVerifier", e); log.error("Error in SignatureVerifierPlugin", e);
} catch (NoSuchAlgorithmException e) {
log.error("Error in SignatureVerifier", e);
} }
return false; return false;
} }
public List<String> shortHashes() {
List<String> hashes = new ArrayList<>();
try {
Signature[] signatures = MainApp.instance().getPackageManager().getPackageInfo(MainApp.instance().getPackageName(), PackageManager.GET_SIGNATURES).signatures;
if (signatures != null) {
for (Signature signature : signatures) {
MessageDigest digest = MessageDigest.getInstance("SHA256");
byte[] fingerprint = digest.digest(signature.toByteArray());
String hash = Hex.toHexString(fingerprint);
log.debug("Found signature: " + hash);
log.debug("Found signature (short): " + singleCharMap(fingerprint));
hashes.add(singleCharMap(fingerprint));
}
}
} catch (PackageManager.NameNotFoundException | NoSuchAlgorithmException e) {
log.error("Error in SignatureVerifierPlugin", e);
}
return hashes;
}
String map = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!\"§$%&/()=?,.-;:_<>|°^`´\\@€*'#+~{}[]¿¡áéíóúàèìòùöäü`ÁÉÍÓÚÀÈÌÒÙÖÄÜßÆÇÊËÎÏԌ۟æçêëîïôœûÿĆČĐŠŽćđšžñΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ\u03A2ΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρςστυφχψωϨϩϪϫϬϭϮϯϰϱϲϳϴϵ϶ϷϸϹϺϻϼϽϾϿЀЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗ";
private String singleCharMap(byte[] array) {
StringBuilder sb = new StringBuilder();
for (byte b : array) {
sb.append(map.charAt(b & 0xFF));
}
return sb.toString();
}
public String singleCharUnMap(String shortHash) {
byte[] array = new byte[shortHash.length()];
StringBuilder sb = new StringBuilder();
for (int i = 0; i < array.length; i++) {
if (i != 0) sb.append(":");
sb.append(String.format("%02X", 0xFF & map.charAt(map.indexOf(shortHash.charAt(i)))));
}
return sb.toString();
}
private boolean shouldDownloadCerts() { private boolean shouldDownloadCerts() {
return System.currentTimeMillis() - SP.getLong(R.string.key_last_revoked_certs_check, 0L) >= UPDATE_INTERVAL; return System.currentTimeMillis() - SP.getLong(R.string.key_last_revoked_certs_check, 0L) >= UPDATE_INTERVAL;
} }
@ -153,7 +191,7 @@ public class SignatureVerifier extends PluginBase implements ConstraintsInterfac
this.revokedCerts = parseRevokedCertsFile(revokedCerts); this.revokedCerts = parseRevokedCertsFile(revokedCerts);
} }
} catch (IOException e) { } catch (IOException e) {
log.error("Error in SignatureVerifier", e); log.error("Error in SignatureVerifierPlugin", e);
} }
} }

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.general.versionChecker package info.nightscout.androidaps.plugins.constraints.versionChecker
import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R import info.nightscout.androidaps.R

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.general.versionChecker package info.nightscout.androidaps.plugins.constraints.versionChecker
import android.content.Context import android.content.Context
import android.net.ConnectivityManager import android.net.ConnectivityManager
@ -15,21 +15,14 @@ import java.io.IOException
import java.net.URL import java.net.URL
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
// check network connection // check network connection
fun isConnected(): Boolean { fun isConnected(): Boolean {
val connMgr = MainApp.instance().applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager val connMgr = MainApp.instance().applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
return connMgr.activeNetworkInfo?.isConnected ?: false return connMgr.activeNetworkInfo?.isConnected ?: false
} }
fun findVersion(file :String?): String? {
val regex = "(.*)version(.*)\"(((\\d+)\\.)+(\\d+))\"(.*)".toRegex()
return file?.lines()?.filter { regex.matches(it) }?.mapNotNull { regex.matchEntire(it)?.groupValues?.getOrNull(3) }?.firstOrNull()
}
private val log = LoggerFactory.getLogger(L.CORE) private val log = LoggerFactory.getLogger(L.CORE)
fun triggerCheckVersion() { fun triggerCheckVersion() {
if (!SP.contains(R.string.key_last_time_this_version_detected)) { if (!SP.contains(R.string.key_last_time_this_version_detected)) {
@ -56,13 +49,34 @@ private fun checkVersion() = if (isConnected()) {
log.debug("Github master version no checked. No connectivity") log.debug("Github master version no checked. No connectivity")
fun compareWithCurrentVersion(newVersion: String?, currentVersion: String) { fun compareWithCurrentVersion(newVersion: String?, currentVersion: String) {
val comparison: Int? = newVersion?.versionStrip()?.compareTo(currentVersion.versionStrip())
when { val newVersionElements = newVersion.toNumberList()
comparison == null -> onVersionNotDetectable() val currentVersionElements = currentVersion.toNumberList()
comparison == 0 -> onSameVersionDetected()
comparison > 0 -> onNewVersionDetected(currentVersion = currentVersion, newVersion = newVersion) if (newVersionElements == null || newVersionElements.isEmpty()) {
else -> onOlderVersionDetected() onVersionNotDetectable()
return
} }
if (currentVersionElements == null || currentVersionElements.isEmpty()) {
// current version scrambled?!
onNewVersionDetected(currentVersion, newVersion)
return
}
newVersionElements.take(3).forEachIndexed { i, newElem ->
val currElem: Int = currentVersionElements.getOrNull(i)
?: return onNewVersionDetected(currentVersion, newVersion)
(newElem - currElem).let {
when {
it > 0 -> return onNewVersionDetected(currentVersion, newVersion)
it < 0 -> return onOlderVersionDetected()
it == 0 -> Unit
}
}
}
onSameVersionDetected()
} }
private fun onOlderVersionDetected() { private fun onOlderVersionDetected() {
@ -75,7 +89,7 @@ fun onSameVersionDetected() {
} }
fun onVersionNotDetectable() { fun onVersionNotDetectable() {
log.debug("fetch failed, ignore and smartcast to non-null") log.debug("fetch failed")
} }
fun onNewVersionDetected(currentVersion: String, newVersion: String?) { fun onNewVersionDetected(currentVersion: String, newVersion: String?) {
@ -88,14 +102,25 @@ fun onNewVersionDetected(currentVersion: String, newVersion: String?) {
} }
} }
@Deprecated(replaceWith = ReplaceWith("numericVersionPart()"), message = "Will not work if RCs have another index number in it.")
fun String.versionStrip() = this.mapNotNull { fun String.versionStrip() = this.mapNotNull {
when (it) { when (it) {
in '0'..'9' -> it in '0'..'9' -> it
'.' -> it '.' -> it
else -> null else -> null
} }
}.joinToString(separator = "") }.joinToString(separator = "")
fun String.numericVersionPart(): String =
"(((\\d+)\\.)+(\\d+))(\\D(.*))?".toRegex().matchEntire(this)?.groupValues?.getOrNull(1) ?: ""
fun String?.toNumberList() =
this?.numericVersionPart().takeIf { !it.isNullOrBlank() }?.split(".")?.map { it.toInt() }
fun findVersion(file: String?): String? {
val regex = "(.*)version(.*)\"(((\\d+)\\.)+(\\d+))\"(.*)".toRegex()
return file?.lines()?.filter { regex.matches(it) }?.mapNotNull { regex.matchEntire(it)?.groupValues?.getOrNull(3) }?.firstOrNull()
}
val CHECK_EVERY = TimeUnit.DAYS.toMillis(1) val CHECK_EVERY = TimeUnit.DAYS.toMillis(1)
val WARN_EVERY = TimeUnit.DAYS.toMillis(1) val WARN_EVERY = TimeUnit.DAYS.toMillis(1)

View file

@ -1,329 +0,0 @@
package info.nightscout.androidaps.plugins.general.actions;
import android.app.Activity;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import androidx.fragment.app.FragmentManager;
import com.squareup.otto.Subscribe;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import info.nightscout.androidaps.Config;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.activities.HistoryBrowseActivity;
import info.nightscout.androidaps.activities.TDDStatsActivity;
import info.nightscout.androidaps.db.ExtendedBolus;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.events.EventCustomActionsChanged;
import info.nightscout.androidaps.events.EventExtendedBolusChange;
import info.nightscout.androidaps.events.EventInitializationChanged;
import info.nightscout.androidaps.events.EventRefreshOverview;
import info.nightscout.androidaps.events.EventTempBasalChange;
import info.nightscout.androidaps.interfaces.PumpInterface;
import info.nightscout.androidaps.plugins.common.SubscriberFragment;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction;
import info.nightscout.androidaps.plugins.general.actions.dialogs.FillDialog;
import info.nightscout.androidaps.plugins.general.actions.dialogs.NewExtendedBolusDialog;
import info.nightscout.androidaps.plugins.general.actions.dialogs.NewTempBasalDialog;
import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment;
import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog;
import info.nightscout.androidaps.plugins.general.careportal.OptionsToShow;
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.utils.SP;
import info.nightscout.androidaps.utils.SingleClickButton;
public class ActionsFragment extends SubscriberFragment implements View.OnClickListener {
private View actionsFragmentView;
private SingleClickButton profileSwitch;
private SingleClickButton tempTarget;
private SingleClickButton extendedBolus;
private SingleClickButton extendedBolusCancel;
private SingleClickButton tempBasal;
private SingleClickButton tempBasalCancel;
private SingleClickButton fill;
private SingleClickButton tddStats;
private SingleClickButton history;
private Map<String, CustomAction> pumpCustomActions = new HashMap<>();
private List<SingleClickButton> pumpCustomButtons = new ArrayList<>();
public ActionsFragment() {
super();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.actions_fragment, container, false);
profileSwitch = view.findViewById(R.id.actions_profileswitch);
tempTarget = view.findViewById(R.id.actions_temptarget);
extendedBolus = view.findViewById(R.id.actions_extendedbolus);
extendedBolusCancel = view.findViewById(R.id.actions_extendedbolus_cancel);
tempBasal = view.findViewById(R.id.actions_settempbasal);
tempBasalCancel = view.findViewById(R.id.actions_canceltempbasal);
fill = view.findViewById(R.id.actions_fill);
tddStats = view.findViewById(R.id.actions_tddstats);
history = view.findViewById(R.id.actions_historybrowser);
profileSwitch.setOnClickListener(this);
tempTarget.setOnClickListener(this);
extendedBolus.setOnClickListener(this);
extendedBolusCancel.setOnClickListener(this);
tempBasal.setOnClickListener(this);
tempBasalCancel.setOnClickListener(this);
fill.setOnClickListener(this);
history.setOnClickListener(this);
tddStats.setOnClickListener(this);
actionsFragmentView = view;
updateGUI();
SP.putBoolean(R.string.key_objectiveuseactions, true);
return view;
}
@Subscribe
public void onStatusEvent(final EventInitializationChanged ev) {
updateGUI();
}
@Subscribe
public void onStatusEvent(final EventRefreshOverview ev) {
updateGUI();
}
@Subscribe
public void onStatusEvent(final EventExtendedBolusChange ev) {
updateGUI();
}
@Subscribe
public void onStatusEvent(final EventTempBasalChange ev) {
updateGUI();
}
@Subscribe
public void onStatusEvent(final EventCustomActionsChanged ev) {
updateGUI();
}
@Override
protected void updateGUI() {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
if (ConfigBuilderPlugin.getPlugin().getActiveProfileInterface() != null && ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getProfile() != null) {
profileSwitch.setVisibility(View.VISIBLE);
} else {
profileSwitch.setVisibility(View.GONE);
}
if (ProfileFunctions.getInstance().getProfile() == null) {
tempTarget.setVisibility(View.GONE);
extendedBolus.setVisibility(View.GONE);
extendedBolusCancel.setVisibility(View.GONE);
tempBasal.setVisibility(View.GONE);
tempBasalCancel.setVisibility(View.GONE);
fill.setVisibility(View.GONE);
return;
}
final PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump();
final boolean basalprofileEnabled = MainApp.isEngineeringModeOrRelease()
&& pump.getPumpDescription().isSetBasalProfileCapable;
if (!basalprofileEnabled || !pump.isInitialized() || pump.isSuspended())
profileSwitch.setVisibility(View.GONE);
else
profileSwitch.setVisibility(View.VISIBLE);
if (!pump.getPumpDescription().isExtendedBolusCapable || !pump.isInitialized() || pump.isSuspended() || pump.isFakingTempsByExtendedBoluses()) {
extendedBolus.setVisibility(View.GONE);
extendedBolusCancel.setVisibility(View.GONE);
} else {
ExtendedBolus activeExtendedBolus = TreatmentsPlugin.getPlugin().getExtendedBolusFromHistory(System.currentTimeMillis());
if (activeExtendedBolus != null) {
extendedBolus.setVisibility(View.GONE);
extendedBolusCancel.setVisibility(View.VISIBLE);
extendedBolusCancel.setText(MainApp.gs(R.string.cancel) + " " + activeExtendedBolus.toString());
} else {
extendedBolus.setVisibility(View.VISIBLE);
extendedBolusCancel.setVisibility(View.GONE);
}
}
if (!pump.getPumpDescription().isTempBasalCapable || !pump.isInitialized() || pump.isSuspended()) {
tempBasal.setVisibility(View.GONE);
tempBasalCancel.setVisibility(View.GONE);
} else {
final TemporaryBasal activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(System.currentTimeMillis());
if (activeTemp != null) {
tempBasal.setVisibility(View.GONE);
tempBasalCancel.setVisibility(View.VISIBLE);
tempBasalCancel.setText(MainApp.gs(R.string.cancel) + " " + activeTemp.toStringShort());
} else {
tempBasal.setVisibility(View.VISIBLE);
tempBasalCancel.setVisibility(View.GONE);
}
}
if (!pump.getPumpDescription().isRefillingCapable || !pump.isInitialized() || pump.isSuspended())
fill.setVisibility(View.GONE);
else
fill.setVisibility(View.VISIBLE);
if (!Config.APS)
tempTarget.setVisibility(View.GONE);
else
tempTarget.setVisibility(View.VISIBLE);
if (!pump.getPumpDescription().supportsTDDs)
tddStats.setVisibility(View.GONE);
else
tddStats.setVisibility(View.VISIBLE);
checkPumpCustomActions();
}
});
}
View.OnClickListener pumpCustomActionsListener = v -> {
SingleClickButton btn = (SingleClickButton) v;
CustomAction customAction = this.pumpCustomActions.get(btn.getText().toString());
ConfigBuilderPlugin.getPlugin().getActivePump().executeCustomAction(customAction.getCustomActionType());
};
private void checkPumpCustomActions() {
PumpInterface activePump = ConfigBuilderPlugin.getPlugin().getActivePump();
removePumpCustomActions();
if (activePump == null) {
return;
}
List<CustomAction> customActions = activePump.getCustomActions();
if (customActions != null && customActions.size() > 0) {
LinearLayout ll = actionsFragmentView.findViewById(R.id.action_buttons_layout);
for (CustomAction customAction : customActions) {
if (!customAction.isEnabled())
continue;
SingleClickButton btn = new SingleClickButton(getContext(), null, android.R.attr.buttonStyle);
btn.setText(MainApp.gs(customAction.getName()));
LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 0.5f);
layoutParams.setMargins(20, 8, 20, 8); // 10,3,10,3
btn.setLayoutParams(layoutParams);
btn.setOnClickListener(pumpCustomActionsListener);
Drawable top = getResources().getDrawable(customAction.getIconResourceId());
btn.setCompoundDrawablesWithIntrinsicBounds(null, top, null, null);
ll.addView(btn);
this.pumpCustomActions.put(MainApp.gs(customAction.getName()), customAction);
this.pumpCustomButtons.add(btn);
}
}
}
private void removePumpCustomActions() {
if (pumpCustomActions.size() == 0)
return;
LinearLayout ll = actionsFragmentView.findViewById(R.id.action_buttons_layout);
for (SingleClickButton customButton : pumpCustomButtons) {
ll.removeView(customButton);
}
pumpCustomButtons.clear();
}
@Override
public void onClick(View view) {
FragmentManager manager = getFragmentManager();
switch (view.getId()) {
case R.id.actions_profileswitch:
NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog();
final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCH;
profileswitch.executeProfileSwitch = true;
newDialog.setOptions(profileswitch, R.string.careportal_profileswitch);
newDialog.show(manager, "NewNSTreatmentDialog");
break;
case R.id.actions_temptarget:
NewNSTreatmentDialog newTTDialog = new NewNSTreatmentDialog();
final OptionsToShow temptarget = CareportalFragment.TEMPTARGET;
temptarget.executeTempTarget = true;
newTTDialog.setOptions(temptarget, R.string.careportal_temporarytarget);
newTTDialog.show(manager, "NewNSTreatmentDialog");
break;
case R.id.actions_extendedbolus:
NewExtendedBolusDialog newExtendedDialog = new NewExtendedBolusDialog();
newExtendedDialog.show(manager, "NewExtendedDialog");
break;
case R.id.actions_extendedbolus_cancel:
if (TreatmentsPlugin.getPlugin().isInHistoryExtendedBoluslInProgress()) {
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelExtended(null);
}
break;
case R.id.actions_canceltempbasal:
if (TreatmentsPlugin.getPlugin().isTempBasalInProgress()) {
ConfigBuilderPlugin.getPlugin().getCommandQueue().cancelTempBasal(true, null);
}
break;
case R.id.actions_settempbasal:
NewTempBasalDialog newTempDialog = new NewTempBasalDialog();
newTempDialog.show(manager, "NewTempDialog");
break;
case R.id.actions_fill:
FillDialog fillDialog = new FillDialog();
fillDialog.show(manager, "FillDialog");
break;
case R.id.actions_historybrowser:
startActivity(new Intent(getContext(), HistoryBrowseActivity.class));
break;
case R.id.actions_tddstats:
startActivity(new Intent(getContext(), TDDStatsActivity.class));
break;
}
}
}

View file

@ -0,0 +1,242 @@
package info.nightscout.androidaps.plugins.general.actions
import android.content.Intent
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.fragment.app.Fragment
import info.nightscout.androidaps.Config
import info.nightscout.androidaps.MainApp
import info.nightscout.androidaps.R
import info.nightscout.androidaps.activities.HistoryBrowseActivity
import info.nightscout.androidaps.activities.TDDStatsActivity
import info.nightscout.androidaps.events.*
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.actions.defs.CustomAction
import info.nightscout.androidaps.plugins.general.actions.dialogs.FillDialog
import info.nightscout.androidaps.plugins.general.actions.dialogs.NewExtendedBolusDialog
import info.nightscout.androidaps.plugins.general.actions.dialogs.NewTempBasalDialog
import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment
import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.*
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import kotlinx.android.synthetic.main.actions_fragment.*
import java.util.*
class ActionsFragment : Fragment() {
private var disposable: CompositeDisposable = CompositeDisposable()
private val pumpCustomActions = HashMap<String, CustomAction>()
private val pumpCustomButtons = ArrayList<SingleClickButton>()
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
return inflater.inflate(R.layout.actions_fragment, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
actions_profileswitch.setOnClickListener {
val newDialog = NewNSTreatmentDialog()
val profileSwitch = CareportalFragment.PROFILESWITCH
profileSwitch.executeProfileSwitch = true
newDialog.setOptions(profileSwitch, R.string.careportal_profileswitch)
fragmentManager?.let { newDialog.show(it, "NewNSTreatmentDialog") }
}
actions_temptarget.setOnClickListener {
val newTTDialog = NewNSTreatmentDialog()
val temptarget = CareportalFragment.TEMPTARGET
temptarget.executeTempTarget = true
newTTDialog.setOptions(temptarget, R.string.careportal_temporarytarget)
fragmentManager?.let { newTTDialog.show(it, "NewNSTreatmentDialog") }
}
actions_extendedbolus.setOnClickListener {
fragmentManager?.let { NewExtendedBolusDialog().show(it, "NewExtendedDialog") }
}
actions_extendedbolus_cancel.setOnClickListener {
if (TreatmentsPlugin.getPlugin().isInHistoryExtendedBoluslInProgress) {
ConfigBuilderPlugin.getPlugin().commandQueue.cancelExtended(object : Callback() {
override fun run() {
if (!result.success)
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.extendedbolusdeliveryerror))
}
})
}
}
actions_settempbasal.setOnClickListener { fragmentManager?.let { NewTempBasalDialog().show(it, "NewTempDialog") } }
actions_canceltempbasal.setOnClickListener {
if (TreatmentsPlugin.getPlugin().isTempBasalInProgress) {
ConfigBuilderPlugin.getPlugin().commandQueue.cancelTempBasal(true, object : Callback() {
override fun run() {
if (!result.success)
ToastUtils.showToastInUiThread(MainApp.instance().applicationContext, MainApp.gs(R.string.tempbasaldeliveryerror))
}
})
}
}
actions_fill.setOnClickListener { fragmentManager?.let { FillDialog().show(it, "FillDialog") } }
actions_historybrowser.setOnClickListener { startActivity(Intent(context, HistoryBrowseActivity::class.java)) }
actions_tddstats.setOnClickListener { startActivity(Intent(context, TDDStatsActivity::class.java)) }
SP.putBoolean(R.string.key_objectiveuseactions, true)
}
@Synchronized
override fun onResume() {
super.onResume()
disposable += RxBus
.toObservable(EventInitializationChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
updateGui()
}, {
FabricPrivacy.logException(it)
})
disposable += RxBus
.toObservable(EventRefreshOverview::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
updateGui()
}, {
FabricPrivacy.logException(it)
})
disposable += RxBus
.toObservable(EventExtendedBolusChange::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
updateGui()
}, {
FabricPrivacy.logException(it)
})
disposable += RxBus
.toObservable(EventTempBasalChange::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
updateGui()
}, {
FabricPrivacy.logException(it)
})
disposable += RxBus
.toObservable(EventCustomActionsChanged::class.java)
.observeOn(AndroidSchedulers.mainThread())
.subscribe({
updateGui()
}, {
FabricPrivacy.logException(it)
})
updateGui()
}
@Synchronized
override fun onPause() {
super.onPause()
disposable.clear()
}
@Synchronized
fun updateGui() {
actions_profileswitch?.visibility =
if (ConfigBuilderPlugin.getPlugin().activeProfileInterface?.profile != null) View.VISIBLE
else View.GONE
if (ProfileFunctions.getInstance().profile == null) {
actions_temptarget?.visibility = View.GONE
actions_extendedbolus?.visibility = View.GONE
actions_extendedbolus_cancel?.visibility = View.GONE
actions_settempbasal?.visibility = View.GONE
actions_canceltempbasal?.visibility = View.GONE
actions_fill?.visibility = View.GONE
return
}
val pump = ConfigBuilderPlugin.getPlugin().activePump ?: return
val basalProfileEnabled = MainApp.isEngineeringModeOrRelease() && pump.pumpDescription.isSetBasalProfileCapable
actions_profileswitch?.visibility = if (!basalProfileEnabled || !pump.isInitialized || pump.isSuspended) View.GONE else View.VISIBLE
if (!pump.pumpDescription.isExtendedBolusCapable || !pump.isInitialized || pump.isSuspended || pump.isFakingTempsByExtendedBoluses || Config.APS) {
actions_extendedbolus?.visibility = View.GONE
actions_extendedbolus_cancel?.visibility = View.GONE
} else {
val activeExtendedBolus = TreatmentsPlugin.getPlugin().getExtendedBolusFromHistory(System.currentTimeMillis())
if (activeExtendedBolus != null) {
actions_extendedbolus?.visibility = View.GONE
actions_extendedbolus_cancel?.visibility = View.VISIBLE
actions_extendedbolus_cancel?.text = MainApp.gs(R.string.cancel) + " " + activeExtendedBolus.toString()
} else {
actions_extendedbolus?.visibility = View.VISIBLE
actions_extendedbolus_cancel?.visibility = View.GONE
}
}
if (!pump.pumpDescription.isTempBasalCapable || !pump.isInitialized || pump.isSuspended) {
actions_settempbasal?.visibility = View.GONE
actions_canceltempbasal?.visibility = View.GONE
} else {
val activeTemp = TreatmentsPlugin.getPlugin().getTempBasalFromHistory(System.currentTimeMillis())
if (activeTemp != null) {
actions_settempbasal?.visibility = View.GONE
actions_canceltempbasal?.visibility = View.VISIBLE
actions_canceltempbasal?.text = MainApp.gs(R.string.cancel) + " " + activeTemp.toStringShort()
} else {
actions_settempbasal?.visibility = View.VISIBLE
actions_canceltempbasal?.visibility = View.GONE
}
}
actions_fill?.visibility =
if (!pump.pumpDescription.isRefillingCapable || !pump.isInitialized || pump.isSuspended) View.GONE
else View.VISIBLE
actions_temptarget?.visibility = if (!Config.APS) View.GONE else View.VISIBLE
actions_tddstats?.visibility = if (!pump.pumpDescription.supportsTDDs) View.GONE else View.VISIBLE
checkPumpCustomActions()
}
private fun checkPumpCustomActions() {
val activePump = ConfigBuilderPlugin.getPlugin().activePump ?: return
val customActions = activePump.customActions ?: return
removePumpCustomActions()
for (customAction in customActions) {
if (!customAction.isEnabled) continue
val btn = SingleClickButton(context, null, android.R.attr.buttonStyle)
btn.text = MainApp.gs(customAction.name)
val layoutParams = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT, 0.5f)
layoutParams.setMargins(20, 8, 20, 8) // 10,3,10,3
btn.layoutParams = layoutParams
btn.setOnClickListener { v ->
val b = v as SingleClickButton
val action = this.pumpCustomActions[b.text.toString()]
ConfigBuilderPlugin.getPlugin().activePump!!.executeCustomAction(action!!.customActionType)
}
val top = resources.getDrawable(customAction.iconResourceId)
btn.setCompoundDrawablesWithIntrinsicBounds(null, top, null, null)
action_buttons_layout?.addView(btn)
this.pumpCustomActions[MainApp.gs(customAction.name)] = customAction
this.pumpCustomButtons.add(btn)
}
}
private fun removePumpCustomActions() {
for (customButton in pumpCustomButtons) action_buttons_layout?.removeView(customButton)
pumpCustomButtons.clear()
}
}

Some files were not shown because too many files have changed in this diff Show more