Add STARTING_STOPPING state, use flags for reasons disabled.

This commit is contained in:
akwizgran
2020-01-30 14:49:22 +00:00
parent a6bd59d3c9
commit 802e599f09
11 changed files with 127 additions and 115 deletions

View File

@@ -8,7 +8,4 @@ public interface BluetoothConstants {
String PROP_ADDRESS = "address"; String PROP_ADDRESS = "address";
String PROP_UUID = "uuid"; String PROP_UUID = "uuid";
// Reason code returned by Plugin#getReasonDisabled()
int REASON_NO_BT_ADAPTER = 2;
} }

View File

@@ -13,8 +13,13 @@ public interface Plugin {
enum State { enum State {
/** /**
* The plugin has not been started, has been stopped, or is disabled by * The plugin has not finished starting or has been stopped.
* settings. */
STARTING_STOPPING,
/**
* The plugin is disabled by settings. Use {@link #getReasonsDisabled()}
* to find out which settings are responsible.
*/ */
DISABLED, DISABLED,
@@ -42,14 +47,7 @@ public interface Plugin {
String PREF_PLUGIN_ENABLE = "enable"; String PREF_PLUGIN_ENABLE = "enable";
/** /**
* Reason code returned by {@link #getReasonDisabled()} to indicate that * Reason flag returned by {@link #getReasonsDisabled()} to indicate that
* the plugin is disabled because it has not been started or has been
* stopped.
*/
int REASON_STARTING_STOPPING = 0;
/**
* Reason code returned by {@link #getReasonDisabled()} to indicate that
* the plugin has been disabled by the user. * the plugin has been disabled by the user.
*/ */
int REASON_USER = 1; int REASON_USER = 1;
@@ -85,14 +83,13 @@ public interface Plugin {
State getState(); State getState();
/** /**
* Returns an integer code indicating why the plugin is * Returns a set of flags indicating why the plugin is
* {@link State#DISABLED disabled}, or -1 if the plugin is not disabled. * {@link State#DISABLED disabled}, or 0 if the plugin is not disabled.
* <p> * <p>
* The codes used are plugin-specific, except the generic codes * The flags used are plugin-specific, except the generic flag
* {@link #REASON_STARTING_STOPPING} and {@link #REASON_USER}, which may * {@link #REASON_USER}, which may be used by any plugin.
* be used by any plugin.
*/ */
int getReasonDisabled(); int getReasonsDisabled();
/** /**
* Returns true if the plugin should be polled periodically to attempt to * Returns true if the plugin should be polled periodically to attempt to

View File

@@ -24,8 +24,18 @@ public interface TorConstants {
// TODO: Remove when settings migration code is removed // TODO: Remove when settings migration code is removed
int PREF_TOR_NETWORK_NEVER = 3; int PREF_TOR_NETWORK_NEVER = 3;
// Reason codes returned by Plugin#getReasonDisabled() /**
* Reason flag returned by {@link Plugin#getReasonsDisabled()}.
*/
int REASON_BATTERY = 2; int REASON_BATTERY = 2;
int REASON_MOBILE_DATA = 3;
int REASON_COUNTRY_BLOCKED = 4; /**
* Reason flag returned by {@link Plugin#getReasonsDisabled()}.
*/
int REASON_MOBILE_DATA = 4;
/**
* Reason flag returned by {@link Plugin#getReasonsDisabled()}.
*/
int REASON_COUNTRY_BLOCKED = 8;
} }

View File

@@ -50,7 +50,7 @@ import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger; import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.plugin.Plugin.PREF_PLUGIN_ENABLE; import static org.briarproject.bramble.api.plugin.Plugin.PREF_PLUGIN_ENABLE;
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE; import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED; import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
import static org.briarproject.bramble.util.LogUtils.logDuration; import static org.briarproject.bramble.util.LogUtils.logDuration;
import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.LogUtils.now; import static org.briarproject.bramble.util.LogUtils.now;
@@ -277,7 +277,7 @@ class PluginManagerImpl implements PluginManager, Service {
private final TransportId id; private final TransportId id;
private final AtomicReference<State> state = private final AtomicReference<State> state =
new AtomicReference<>(DISABLED); new AtomicReference<>(STARTING_STOPPING);
private Callback(TransportId id) { private Callback(TransportId id) {
this.id = id; this.id = id;

View File

@@ -49,11 +49,11 @@ import static org.briarproject.bramble.api.keyagreement.KeyAgreementConstants.TR
import static org.briarproject.bramble.api.plugin.BluetoothConstants.ID; import static org.briarproject.bramble.api.plugin.BluetoothConstants.ID;
import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_ADDRESS; import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_ADDRESS;
import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_UUID; import static org.briarproject.bramble.api.plugin.BluetoothConstants.PROP_UUID;
import static org.briarproject.bramble.api.plugin.BluetoothConstants.REASON_NO_BT_ADAPTER;
import static org.briarproject.bramble.api.plugin.BluetoothConstants.UUID_BYTES; import static org.briarproject.bramble.api.plugin.BluetoothConstants.UUID_BYTES;
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE; import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED; import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED;
import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE; import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE;
import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress; import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty; import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
@@ -163,16 +163,15 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
@Override @Override
public void start() throws PluginException { public void start() throws PluginException {
if (used.getAndSet(true)) throw new IllegalStateException(); if (used.getAndSet(true)) throw new IllegalStateException();
try {
initialiseAdapter();
} catch (IOException e) {
state.setNoAdapter();
throw new PluginException(e);
}
updateProperties();
Settings settings = callback.getSettings(); Settings settings = callback.getSettings();
boolean enabledByUser = settings.getBoolean(PREF_PLUGIN_ENABLE, false); boolean enabledByUser = settings.getBoolean(PREF_PLUGIN_ENABLE, false);
state.setStarted(enabledByUser); state.setStarted(enabledByUser);
try {
initialiseAdapter();
} catch (IOException e) {
throw new PluginException(e);
}
updateProperties();
if (enabledByUser) { if (enabledByUser) {
if (isAdapterEnabled()) bind(); if (isAdapterEnabled()) bind();
else enableAdapter(); else enableAdapter();
@@ -256,8 +255,8 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
} }
@Override @Override
public int getReasonDisabled() { public int getReasonsDisabled() {
return state.getReasonDisabled(); return state.getReasonsDisabled();
} }
@Override @Override
@@ -477,7 +476,6 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
@GuardedBy("this") @GuardedBy("this")
private boolean started = false, private boolean started = false,
stopped = false, stopped = false,
noAdapter = false,
enabledByUser = false; enabledByUser = false;
@GuardedBy("this") @GuardedBy("this")
@@ -499,11 +497,6 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
return ss; return ss;
} }
synchronized void setNoAdapter() {
noAdapter = true;
callback.pluginStateChanged(getState());
}
@Nullable @Nullable
synchronized SS setEnabledByUser(boolean enabledByUser) { synchronized SS setEnabledByUser(boolean enabledByUser) {
this.enabledByUser = enabledByUser; this.enabledByUser = enabledByUser;
@@ -532,14 +525,13 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
} }
synchronized State getState() { synchronized State getState() {
if (!started || stopped || !enabledByUser) return DISABLED; if (!started || stopped) return STARTING_STOPPING;
if (!enabledByUser) return DISABLED;
return serverSocket == null ? INACTIVE : ACTIVE; return serverSocket == null ? INACTIVE : ACTIVE;
} }
synchronized int getReasonDisabled() { synchronized int getReasonsDisabled() {
if (noAdapter && !stopped) return REASON_NO_BT_ADAPTER; return getState() == DISABLED ? REASON_USER : 0;
if (!started || stopped) return REASON_STARTING_STOPPING;
return enabledByUser ? -1 : REASON_USER;
} }
} }
} }

View File

@@ -51,6 +51,7 @@ import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE; import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED; import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED;
import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE; import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE;
import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
import static org.briarproject.bramble.util.IoUtils.tryToClose; import static org.briarproject.bramble.util.IoUtils.tryToClose;
import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress; import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress;
@@ -205,8 +206,8 @@ abstract class TcpPlugin implements DuplexPlugin, EventListener {
} }
@Override @Override
public int getReasonDisabled() { public int getReasonsDisabled() {
return state.getReasonDisabled(); return state.getReasonsDisabled();
} }
@Override @Override
@@ -455,13 +456,13 @@ abstract class TcpPlugin implements DuplexPlugin, EventListener {
} }
synchronized State getState() { synchronized State getState() {
if (!started || stopped || !enabledByUser) return DISABLED; if (!started || stopped) return STARTING_STOPPING;
if (!enabledByUser) return DISABLED;
return serverSocket == null ? INACTIVE : ACTIVE; return serverSocket == null ? INACTIVE : ACTIVE;
} }
synchronized int getReasonDisabled() { synchronized int getReasonsDisabled() {
if (!started || stopped) return REASON_STARTING_STOPPING; return getState() == DISABLED ? REASON_USER : 0;
return enabledByUser ? -1 : REASON_USER;
} }
} }
} }

View File

@@ -73,6 +73,7 @@ import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED; import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED;
import static org.briarproject.bramble.api.plugin.Plugin.State.ENABLING; import static org.briarproject.bramble.api.plugin.Plugin.State.ENABLING;
import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE; import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE;
import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
import static org.briarproject.bramble.api.plugin.TorConstants.CONTROL_PORT; import static org.briarproject.bramble.api.plugin.TorConstants.CONTROL_PORT;
import static org.briarproject.bramble.api.plugin.TorConstants.ID; import static org.briarproject.bramble.api.plugin.TorConstants.ID;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_MOBILE; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_MOBILE;
@@ -533,8 +534,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
} }
@Override @Override
public int getReasonDisabled() { public int getReasonsDisabled() {
return state.getReasonDisabled(); return state.getReasonsDisabled();
} }
@Override @Override
@@ -773,7 +774,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
String country = locationUtils.getCurrentCountry(); String country = locationUtils.getCurrentCountry();
boolean blocked = boolean blocked =
circumventionProvider.isTorProbablyBlocked(country); circumventionProvider.isTorProbablyBlocked(country);
boolean enabledByUser = settings.getBoolean(PREF_PLUGIN_ENABLE, true); boolean enabledByUser =
settings.getBoolean(PREF_PLUGIN_ENABLE, true);
int network = settings.getInt(PREF_TOR_NETWORK, int network = settings.getInt(PREF_TOR_NETWORK,
PREF_TOR_NETWORK_AUTOMATIC); PREF_TOR_NETWORK_AUTOMATIC);
boolean useMobile = settings.getBoolean(PREF_TOR_MOBILE, true); boolean useMobile = settings.getBoolean(PREF_TOR_MOBILE, true);
@@ -789,54 +791,58 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
LOG.info("Charging: " + charging); LOG.info("Charging: " + charging);
} }
int reasonsDisabled = 0;
boolean enableNetwork = false, enableBridges = false; boolean enableNetwork = false, enableBridges = false;
boolean useMeek = false, enableConnectionPadding = false; boolean useMeek = false, enableConnectionPadding = false;
boolean disabledBySettings = false;
int reasonDisabled = REASON_STARTING_STOPPING;
if (!online) { if (!online) {
LOG.info("Disabling network, device is offline"); LOG.info("Disabling network, device is offline");
} else if (!enabledByUser) {
LOG.info("Disabling network, user has disabled Tor");
disabledBySettings = true;
reasonDisabled = REASON_USER;
} else if (!charging && onlyWhenCharging) {
LOG.info("Disabling network, device is on battery");
disabledBySettings = true;
reasonDisabled = REASON_BATTERY;
} else if (!useMobile && !wifi) {
LOG.info("Disabling network, device is using mobile data");
disabledBySettings = true;
reasonDisabled = REASON_MOBILE_DATA;
} else if (automatic && blocked && !bridgesWork) {
LOG.info("Disabling network, country is blocked");
disabledBySettings = true;
reasonDisabled = REASON_COUNTRY_BLOCKED;
} else { } else {
LOG.info("Enabling network"); if (!enabledByUser) {
enableNetwork = true; LOG.info("User has disabled Tor");
if (network == PREF_TOR_NETWORK_WITH_BRIDGES || reasonsDisabled |= REASON_USER;
(automatic && bridgesWork)) {
if (circumventionProvider.needsMeek(country)) {
LOG.info("Using meek bridges");
enableBridges = true;
useMeek = true;
} else {
LOG.info("Using obfs4 bridges");
enableBridges = true;
}
} else {
LOG.info("Not using bridges");
} }
if (wifi && charging) { if (!charging && onlyWhenCharging) {
LOG.info("Enabling connection padding"); LOG.info("Configured not to use battery");
enableConnectionPadding = true; reasonsDisabled |= REASON_BATTERY;
}
if (!useMobile && !wifi) {
LOG.info("Configured not to use mobile data");
reasonsDisabled |= REASON_MOBILE_DATA;
}
if (automatic && blocked && !bridgesWork) {
LOG.info("Country is blocked");
reasonsDisabled |= REASON_COUNTRY_BLOCKED;
}
if (reasonsDisabled != 0) {
LOG.info("Disabling network due to settings");
} else { } else {
LOG.info("Disabling connection padding"); LOG.info("Enabling network");
enableNetwork = true;
if (network == PREF_TOR_NETWORK_WITH_BRIDGES ||
(automatic && bridgesWork)) {
if (circumventionProvider.needsMeek(country)) {
LOG.info("Using meek bridges");
enableBridges = true;
useMeek = true;
} else {
LOG.info("Using obfs4 bridges");
enableBridges = true;
}
} else {
LOG.info("Not using bridges");
}
if (wifi && charging) {
LOG.info("Enabling connection padding");
enableConnectionPadding = true;
} else {
LOG.info("Disabling connection padding");
}
} }
} }
state.setDisabledBySettings(disabledBySettings, reasonDisabled); state.setReasonsDisabled(reasonsDisabled);
try { try {
if (enableNetwork) { if (enableNetwork) {
@@ -865,11 +871,10 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
networkEnabled = false, networkEnabled = false,
bootstrapped = false, bootstrapped = false,
circuitBuilt = false, circuitBuilt = false,
settingsChecked = false, settingsChecked = false;
disabledBySettings = false;
@GuardedBy("this") @GuardedBy("this")
private int reasonDisabled = REASON_STARTING_STOPPING; private int reasonsDisabled = 0;
@GuardedBy("this") @GuardedBy("this")
@Nullable @Nullable
@@ -912,11 +917,9 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
callback.pluginStateChanged(getState()); callback.pluginStateChanged(getState());
} }
synchronized void setDisabledBySettings(boolean disabledBySettings, synchronized void setReasonsDisabled(int reasonsDisabled) {
int reasonDisabled) {
settingsChecked = true; settingsChecked = true;
this.disabledBySettings = disabledBySettings; this.reasonsDisabled = reasonsDisabled;
this.reasonDisabled = reasonDisabled;
callback.pluginStateChanged(getState()); callback.pluginStateChanged(getState());
} }
@@ -933,16 +936,17 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
} }
synchronized State getState() { synchronized State getState() {
if (!started || stopped || !settingsChecked || disabledBySettings) { if (!started || stopped || !settingsChecked) {
return DISABLED; return STARTING_STOPPING;
} }
if (reasonsDisabled != 0) return DISABLED;
if (!networkInitialised) return ENABLING; if (!networkInitialised) return ENABLING;
if (!networkEnabled) return INACTIVE; if (!networkEnabled) return INACTIVE;
return bootstrapped && circuitBuilt ? ACTIVE : ENABLING; return bootstrapped && circuitBuilt ? ACTIVE : ENABLING;
} }
synchronized int getReasonDisabled() { synchronized int getReasonsDisabled() {
return getState() == DISABLED ? reasonDisabled : -1; return getState() == DISABLED ? reasonsDisabled : 0;
} }
} }
} }

View File

@@ -31,9 +31,9 @@ import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger; import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE; import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED;
import static org.briarproject.bramble.api.plugin.Plugin.State.ENABLING; import static org.briarproject.bramble.api.plugin.Plugin.State.ENABLING;
import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE; import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE;
import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty; import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
@@ -121,8 +121,8 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
} }
@Override @Override
public int getReasonDisabled() { public int getReasonsDisabled() {
return getState() == DISABLED ? REASON_STARTING_STOPPING : -1; return 0;
} }
@Override @Override
@@ -280,7 +280,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
} }
private State getState() { private State getState() {
if (!started || stopped) return DISABLED; if (!started || stopped) return STARTING_STOPPING;
if (failed) return INACTIVE; if (failed) return INACTIVE;
return initialised ? ACTIVE : ENABLING; return initialised ? ACTIVE : ENABLING;
} }

View File

@@ -53,6 +53,7 @@ import static org.briarproject.bramble.api.nullsafety.NullSafety.requireNonNull;
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE; import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED; import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED;
import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE; import static org.briarproject.bramble.api.plugin.Plugin.State.INACTIVE;
import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_BLUETOOTH_DISCOVERABLE; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_BLUETOOTH_DISCOVERABLE;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PERMISSION_CAMERA_LOCATION; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PERMISSION_CAMERA_LOCATION;
@@ -258,7 +259,9 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
private boolean shouldEnableWifi() { private boolean shouldEnableWifi() {
if (hasEnabledWifi) return false; if (hasEnabledWifi) return false;
Plugin p = pluginManager.getPlugin(LanTcpConstants.ID); Plugin p = pluginManager.getPlugin(LanTcpConstants.ID);
return p != null && p.getState() == DISABLED; if (p == null) return false;
State state = p.getState();
return state == STARTING_STOPPING || state == DISABLED;
} }
private void requestBluetoothDiscoverable() { private void requestBluetoothDiscoverable() {
@@ -284,7 +287,9 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
if (bluetoothDecision != BluetoothDecision.ACCEPTED) return false; if (bluetoothDecision != BluetoothDecision.ACCEPTED) return false;
if (hasEnabledBluetooth) return false; if (hasEnabledBluetooth) return false;
Plugin p = pluginManager.getPlugin(BluetoothConstants.ID); Plugin p = pluginManager.getPlugin(BluetoothConstants.ID);
return p != null && p.getState() == DISABLED; if (p == null) return false;
State state = p.getState();
return state == STARTING_STOPPING || state == DISABLED;
} }
@Override @Override

View File

@@ -34,7 +34,7 @@ import static java.util.concurrent.TimeUnit.DAYS;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static java.util.logging.Logger.getLogger; import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED; import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.briar.android.TestingConstants.EXPIRY_DATE; import static org.briarproject.briar.android.TestingConstants.EXPIRY_DATE;
import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD; import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
@@ -194,7 +194,7 @@ public class NavDrawerViewModel extends AndroidViewModel
private State getTransportState(TransportId id) { private State getTransportState(TransportId id) {
Plugin plugin = pluginManager.getPlugin(id); Plugin plugin = pluginManager.getPlugin(id);
return plugin == null ? DISABLED : plugin.getState(); return plugin == null ? STARTING_STOPPING : plugin.getState();
} }
@Nullable @Nullable

View File

@@ -17,6 +17,7 @@ import static androidx.core.content.ContextCompat.getColor;
import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE; import static org.briarproject.bramble.api.plugin.Plugin.State.ACTIVE;
import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED; import static org.briarproject.bramble.api.plugin.Plugin.State.DISABLED;
import static org.briarproject.bramble.api.plugin.Plugin.State.ENABLING; import static org.briarproject.bramble.api.plugin.Plugin.State.ENABLING;
import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
import static org.briarproject.briar.android.navdrawer.NavDrawerViewModel.TRANSPORT_IDS; import static org.briarproject.briar.android.navdrawer.NavDrawerViewModel.TRANSPORT_IDS;
class PluginViewController { class PluginViewController {
@@ -38,10 +39,13 @@ class PluginViewController {
for (TransportId t : TRANSPORT_IDS) { for (TransportId t : TRANSPORT_IDS) {
// a OnCheckedChangeListener would get triggered on programmatic updates // a OnCheckedChangeListener would get triggered on programmatic updates
SwitchCompat switchCompat = getSwitch(t); SwitchCompat switchCompat = getSwitch(t);
switchCompat.setOnClickListener(buttonView -> switchCompat.setOnClickListener(buttonView -> {
// TODO check reason first and change settings if needed // TODO check reason first and change settings if needed
viewModel.setPluginEnabled(t, switchCompat.isChecked()) viewModel.setPluginEnabled(t, switchCompat.isChecked());
); // Revert the switch to its previous state until the plugin
// changes its state
switchCompat.toggle();
});
viewModel.getPluginState(t) viewModel.getPluginState(t)
.observe(owner, state -> stateUpdate(t, state)); .observe(owner, state -> stateUpdate(t, state));
} }
@@ -60,7 +64,9 @@ class PluginViewController {
} }
private void updateSwitch(SwitchCompat switchCompat, State state) { private void updateSwitch(SwitchCompat switchCompat, State state) {
switchCompat.setChecked(state != DISABLED); boolean checked = state != STARTING_STOPPING && state != DISABLED;
switchCompat.setChecked(checked);
switchCompat.setEnabled(state != STARTING_STOPPING);
} }
private ImageView getIcon(TransportId id) { private ImageView getIcon(TransportId id) {