PluginBase -> kt

This commit is contained in:
Milos Kozak 2019-12-28 14:12:35 +01:00
parent a98b3ed6ac
commit 3c58559a75
7 changed files with 183 additions and 250 deletions

View file

@ -1,223 +0,0 @@
package info.nightscout.androidaps.interfaces;
import android.os.SystemClock;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import androidx.fragment.app.FragmentActivity;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.plugins.bus.RxBus;
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
import info.nightscout.androidaps.plugins.configBuilder.EventConfigBuilderUpdateGui;
import info.nightscout.androidaps.queue.CommandQueue;
import info.nightscout.androidaps.utils.OKDialog;
import info.nightscout.androidaps.utils.SP;
/**
* Created by mike on 09.06.2016.
*/
public abstract class PluginBase {
private static Logger log = LoggerFactory.getLogger(L.CORE);
public enum State {
NOT_INITIALIZED,
ENABLED,
DISABLED
}
private State state = State.NOT_INITIALIZED;
private boolean isFragmentVisible = false;
public PluginDescription pluginDescription;
// Specific plugin with more Interfaces
protected boolean isProfileInterfaceEnabled = false;
public PluginBase(PluginDescription pluginDescription) {
this.pluginDescription = pluginDescription;
}
// Default always calls invoke
// Plugins that have special constraints if they get switched to may override this method
public void switchAllowed(boolean newState, FragmentActivity activity, PluginType type) {
performPluginSwitch(newState, type);
}
protected void confirmPumpPluginActivation(boolean newState, FragmentActivity activity, PluginType type) {
if (type == PluginType.PUMP) {
boolean allowHardwarePump = SP.getBoolean("allow_hardware_pump", false);
if (allowHardwarePump || activity == null) {
performPluginSwitch(newState, type);
} else {
OKDialog.showConfirmation(activity, MainApp.gs(R.string.allow_hardware_pump_text), () -> {
performPluginSwitch(newState, type);
SP.putBoolean("allow_hardware_pump", true);
if (L.isEnabled(L.PUMP))
log.debug("First time HW pump allowed!");
}, () -> {
RxBus.INSTANCE.send(new EventConfigBuilderUpdateGui());
if (L.isEnabled(L.PUMP))
log.debug("User does not allow switching to HW pump!");
});
}
} else {
performPluginSwitch(newState, type);
}
}
private void performPluginSwitch(boolean enabled, PluginType type) {
setPluginEnabled(type, enabled);
setFragmentVisible(type, enabled);
ConfigBuilderPlugin.getPlugin().processOnEnabledCategoryChanged(this, getType());
ConfigBuilderPlugin.getPlugin().storeSettings("CheckedCheckboxEnabled");
RxBus.INSTANCE.send(new EventRebuildTabs());
RxBus.INSTANCE.send(new EventConfigBuilderChange());
RxBus.INSTANCE.send(new EventConfigBuilderUpdateGui());
ConfigBuilderPlugin.getPlugin().logPluginStatus();
}
public String getName() {
if (pluginDescription.pluginName == -1)
return "UKNOWN";
else
return MainApp.gs(pluginDescription.pluginName);
}
public String getNameShort() {
if (pluginDescription.shortName == -1)
return getName();
String name = MainApp.gs(pluginDescription.shortName);
if (!name.trim().isEmpty()) //only if translation exists
return name;
// use long name as fallback
return getName();
}
public String getDescription() {
if (pluginDescription.description == -1) return null;
else return MainApp.gs(pluginDescription.description);
}
public PluginType getType() {
return pluginDescription.mainType;
}
public int getPreferencesId() {
return pluginDescription.preferencesId;
}
public boolean isEnabled(PluginType type) {
if (pluginDescription.alwaysEnabled && type == pluginDescription.mainType)
return true;
if (pluginDescription.mainType == PluginType.CONSTRAINTS && type == PluginType.CONSTRAINTS)
return true;
if (type == pluginDescription.mainType)
return state == State.ENABLED && specialEnableCondition();
if (type == PluginType.CONSTRAINTS && pluginDescription.mainType == PluginType.PUMP && isEnabled(PluginType.PUMP))
return true;
if (type == PluginType.CONSTRAINTS && pluginDescription.mainType == PluginType.APS && isEnabled(PluginType.APS))
return true;
if (type == PluginType.PROFILE && pluginDescription.mainType == PluginType.PUMP)
return isProfileInterfaceEnabled;
return false;
}
public boolean hasFragment() {
return pluginDescription.fragmentClass != null;
}
/**
* So far plugin can have it's main type + ConstraintInterface + ProfileInterface
* ConstraintInterface is enabled if main plugin is enabled
* ProfileInterface can be enabled only if main iterface is enable
*/
public void setPluginEnabled(PluginType type, boolean newState) {
if (type == pluginDescription.mainType) {
if (newState == true) { // enabling plugin
if (state != State.ENABLED) {
onStateChange(type, state, State.ENABLED);
state = State.ENABLED;
if (L.isEnabled(L.CORE))
log.debug("Starting: " + getName());
onStart();
}
} else { // disabling plugin
if (state == State.ENABLED) {
onStateChange(type, state, State.DISABLED);
state = State.DISABLED;
onStop();
if (L.isEnabled(L.CORE))
log.debug("Stopping: " + getName());
}
}
} else if (type == PluginType.PROFILE) {
isProfileInterfaceEnabled = newState;
}
}
public void setFragmentVisible(PluginType type, boolean fragmentVisible) {
if (type == pluginDescription.mainType) {
isFragmentVisible = fragmentVisible && specialEnableCondition();
}
}
public boolean isFragmentVisible() {
if (pluginDescription.alwaysVisible)
return true;
if (pluginDescription.neverVisible)
return false;
return isFragmentVisible;
}
public boolean showInList(PluginType type) {
if (pluginDescription.mainType == type)
return pluginDescription.showInList && specialShowInListCondition();
if (type == PluginType.PROFILE && pluginDescription.mainType == PluginType.PUMP)
return isEnabled(PluginType.PUMP);
return false;
}
public boolean specialEnableCondition() {
return true;
}
public boolean specialShowInListCondition() {
return true;
}
protected void onStart() {
if (getType() == PluginType.PUMP) {
new Thread(() -> {
SystemClock.sleep(3000);
CommandQueue commandQueue = ConfigBuilderPlugin.getPlugin().getCommandQueue();
if (commandQueue != null)
commandQueue.readStatus("Pump driver changed.", null);
}).start();
}
}
protected void onStop() {
}
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

@ -0,0 +1,180 @@
package info.nightscout.androidaps.interfaces
import android.os.SystemClock
import android.preference.Preference
import android.preference.PreferenceFragment
import androidx.fragment.app.FragmentActivity
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.isEnabled
import info.nightscout.androidaps.plugins.bus.RxBus.send
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
import info.nightscout.androidaps.plugins.configBuilder.EventConfigBuilderUpdateGui
import info.nightscout.androidaps.utils.OKDialog.showConfirmation
import info.nightscout.androidaps.utils.SP
import org.slf4j.LoggerFactory
/**
* Created by mike on 09.06.2016.
*/
abstract class PluginBase(pluginDesc: PluginDescription) {
companion object {
private val log = LoggerFactory.getLogger(L.CORE)
}
enum class State {
NOT_INITIALIZED, ENABLED, DISABLED
}
lateinit var pluginDescription: PluginDescription // TODO: workaround to have pluginDescription accessible in child classes
private var state = State.NOT_INITIALIZED
private var fragmentVisible = false
// Specific plugin with more Interfaces
protected var isProfileInterfaceEnabled = false
init {
pluginDescription = pluginDesc
}
// Default always calls invoke
// Plugins that have special constraints if they get switched to may override this method
open fun switchAllowed(newState: Boolean, activity: FragmentActivity?, type: PluginType) {
performPluginSwitch(newState, type)
}
protected fun confirmPumpPluginActivation(newState: Boolean, activity: FragmentActivity?, type: PluginType) {
if (type == PluginType.PUMP) {
val allowHardwarePump = SP.getBoolean("allow_hardware_pump", false)
if (allowHardwarePump || activity == null) {
performPluginSwitch(newState, type)
} else {
showConfirmation(activity, MainApp.gs(R.string.allow_hardware_pump_text), Runnable {
performPluginSwitch(newState, type)
SP.putBoolean("allow_hardware_pump", true)
if (isEnabled(L.PUMP)) log.debug("First time HW pump allowed!")
}, Runnable {
send(EventConfigBuilderUpdateGui())
if (isEnabled(L.PUMP)) log.debug("User does not allow switching to HW pump!")
})
}
} else {
performPluginSwitch(newState, type)
}
}
private fun performPluginSwitch(enabled: Boolean, type: PluginType) {
setPluginEnabled(type, enabled)
setFragmentVisible(type, enabled)
ConfigBuilderPlugin.getPlugin().processOnEnabledCategoryChanged(this, type)
ConfigBuilderPlugin.getPlugin().storeSettings("CheckedCheckboxEnabled")
send(EventRebuildTabs())
send(EventConfigBuilderChange())
send(EventConfigBuilderUpdateGui())
ConfigBuilderPlugin.getPlugin().logPluginStatus()
}
open val name: String
get() = if (pluginDescription.pluginName == -1) "UNKNOWN" else MainApp.gs(pluginDescription.pluginName)
//only if translation exists
// use long name as fallback
val nameShort: String
get() {
if (pluginDescription.shortName == -1) return name
val translatedName = MainApp.gs(pluginDescription.shortName)
return if (!translatedName.trim { it <= ' ' }.isEmpty()) translatedName else name
// use long name as fallback
}
val description: String?
get() = if (pluginDescription.description == -1) null else MainApp.gs(pluginDescription.description)
val type: PluginType
get() = pluginDescription.mainType
open val preferencesId: Int
get() = pluginDescription.preferencesId
fun isEnabled(type: PluginType): Boolean {
if (pluginDescription.alwaysEnabled && type == pluginDescription.mainType) return true
if (pluginDescription.mainType == PluginType.CONSTRAINTS && type == PluginType.CONSTRAINTS) return true
if (type == pluginDescription.mainType) return state == State.ENABLED && specialEnableCondition()
if (type == PluginType.CONSTRAINTS && pluginDescription.mainType == PluginType.PUMP && isEnabled(PluginType.PUMP)) return true
if (type == PluginType.CONSTRAINTS && pluginDescription.mainType == PluginType.APS && isEnabled(PluginType.APS)) return true
return if (type == PluginType.PROFILE && pluginDescription.mainType == PluginType.PUMP) isProfileInterfaceEnabled else false
}
fun hasFragment(): Boolean {
return pluginDescription.fragmentClass != null
}
/**
* So far plugin can have it's main type + ConstraintInterface + ProfileInterface
* ConstraintInterface is enabled if main plugin is enabled
* ProfileInterface can be enabled only if main iterface is enable
*/
fun setPluginEnabled(type: PluginType, newState: Boolean) {
if (type == pluginDescription.mainType) {
if (newState) { // enabling plugin
if (state != State.ENABLED) {
onStateChange(type, state, State.ENABLED)
state = State.ENABLED
if (isEnabled(L.CORE)) log.debug("Starting: $name")
onStart()
}
} else { // disabling plugin
if (state == State.ENABLED) {
onStateChange(type, state, State.DISABLED)
state = State.DISABLED
onStop()
if (isEnabled(L.CORE)) log.debug("Stopping: $name")
}
}
} else if (type == PluginType.PROFILE) {
isProfileInterfaceEnabled = newState
}
}
fun setFragmentVisible(type: PluginType, fragmentVisible: Boolean) {
if (type == pluginDescription.mainType) {
this.fragmentVisible = fragmentVisible && specialEnableCondition()
}
}
fun isFragmentVisible(): Boolean {
if (pluginDescription.alwaysVisible) return true
return if (pluginDescription.neverVisible) false else fragmentVisible
}
fun showInList(type: PluginType): Boolean {
if (pluginDescription.mainType == type) return pluginDescription.showInList && specialShowInListCondition()
return if (type == PluginType.PROFILE && pluginDescription.mainType == PluginType.PUMP) isEnabled(PluginType.PUMP) else false
}
open fun specialEnableCondition(): Boolean {
return true
}
open fun specialShowInListCondition(): Boolean {
return true
}
protected open fun onStart() {
if (type == PluginType.PUMP) {
Thread(Runnable {
SystemClock.sleep(3000)
val commandQueue = ConfigBuilderPlugin.getPlugin().commandQueue
commandQueue?.readStatus("Pump driver changed.", null)
}).start()
}
}
protected open fun onStop() {}
protected open fun onStateChange(type: PluginType?, oldState: State?, newState: State?) {}
open fun preprocessPreferences(preferenceFragment: PreferenceFragment) {}
open fun updatePreferenceSummary(pref: Preference) {}
}

View file

@ -77,7 +77,7 @@ class PluginViewHolder internal constructor(private val fragment: ConfigBuilderF
pluginPreferences.visibility = if (plugin.preferencesId == -1 || !plugin.isEnabled(pluginType)) View.INVISIBLE else View.VISIBLE pluginPreferences.visibility = if (plugin.preferencesId == -1 || !plugin.isEnabled(pluginType)) View.INVISIBLE else View.VISIBLE
pluginVisibility.visibility = plugin.hasFragment().toVisibility() pluginVisibility.visibility = plugin.hasFragment().toVisibility()
pluginVisibility.isEnabled = !(plugin.pluginDescription.neverVisible || plugin.pluginDescription.alwaysVisible) && plugin.isEnabled(pluginType) pluginVisibility.isEnabled = !(plugin.pluginDescription.neverVisible || plugin.pluginDescription.alwaysVisible) && plugin.isEnabled(pluginType)
pluginVisibility.isChecked = plugin.isFragmentVisible pluginVisibility.isChecked = plugin.isFragmentVisible()
} }
private fun areMultipleSelectionsAllowed(type: PluginType): Boolean { private fun areMultipleSelectionsAllowed(type: PluginType): Boolean {

View file

@ -23,7 +23,7 @@ abstract class InsulinOrefBasePlugin() : PluginBase(PluginDescription()
.visibleByDefault(false) .visibleByDefault(false)
), InsulinInterface { ), InsulinInterface {
var lastWarned: Long = 0 private var lastWarned: Long = 0
override fun getDia(): Double { override fun getDia(): Double {
val dia = userDefinedDia val dia = userDefinedDia
return if (dia >= MIN_DIA) { return if (dia >= MIN_DIA) {
@ -42,7 +42,7 @@ abstract class InsulinOrefBasePlugin() : PluginBase(PluginDescription()
} }
} }
val notificationPattern: String private val notificationPattern: String
get() = MainApp.gs(R.string.dia_too_short) get() = MainApp.gs(R.string.dia_too_short)
open val userDefinedDia: Double open val userDefinedDia: Double

View file

@ -14,10 +14,6 @@ class InsulinOrefUltraRapidActingPlugin @Inject constructor(): InsulinOrefBasePl
return InsulinInterface.OREF_ULTRA_RAPID_ACTING return InsulinInterface.OREF_ULTRA_RAPID_ACTING
} }
override fun getName(): String {
return MainApp.gs(R.string.ultrarapid_oref)
}
override fun getFriendlyName(): String { override fun getFriendlyName(): String {
return MainApp.gs(R.string.ultrarapid_oref) return MainApp.gs(R.string.ultrarapid_oref)
} }

View file

@ -67,16 +67,6 @@ public abstract class AbstractDanaRPlugin extends PluginBase implements PumpInte
); );
} }
@Override
public void onStateChange(PluginType type, State oldState, State newState) {
// if pump profile was enabled need to switch to another too
if (type == PluginType.PUMP && newState == State.DISABLED && isProfileInterfaceEnabled) {
setPluginEnabled(PluginType.PROFILE, false);
NSProfilePlugin.getPlugin().setPluginEnabled(PluginType.PROFILE, true);
NSProfilePlugin.getPlugin().setFragmentVisible(PluginType.PROFILE, true);
}
}
@Override @Override
public void switchAllowed(boolean newState, FragmentActivity activity, PluginType type) { public void switchAllowed(boolean newState, FragmentActivity activity, PluginType type) {
confirmPumpPluginActivation(newState, activity, type); confirmPumpPluginActivation(newState, activity, type);

View file

@ -100,16 +100,6 @@ public class DanaRSPlugin extends PluginBase implements PumpInterface, DanaRInte
pumpDescription.setPumpDescription(PumpType.DanaRS); pumpDescription.setPumpDescription(PumpType.DanaRS);
} }
@Override
public void onStateChange(PluginType type, State oldState, State newState) {
// if pump profile was enabled need to switch to another too
if (type == PluginType.PUMP && newState == State.DISABLED && isProfileInterfaceEnabled) {
setPluginEnabled(PluginType.PROFILE, false);
NSProfilePlugin.getPlugin().setPluginEnabled(PluginType.PROFILE, true);
NSProfilePlugin.getPlugin().setFragmentVisible(PluginType.PROFILE, true);
}
}
@Override @Override
public void updatePreferenceSummary(@NotNull Preference pref) { public void updatePreferenceSummary(@NotNull Preference pref) {
super.updatePreferenceSummary(pref); super.updatePreferenceSummary(pref);