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_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 {
/**
* The plugin has not been started, has been stopped, or is disabled by
* settings.
* The plugin has not finished starting or has been stopped.
*/
STARTING_STOPPING,
/**
* The plugin is disabled by settings. Use {@link #getReasonsDisabled()}
* to find out which settings are responsible.
*/
DISABLED,
@@ -42,14 +47,7 @@ public interface Plugin {
String PREF_PLUGIN_ENABLE = "enable";
/**
* Reason code returned by {@link #getReasonDisabled()} 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
* Reason flag returned by {@link #getReasonsDisabled()} to indicate that
* the plugin has been disabled by the user.
*/
int REASON_USER = 1;
@@ -85,14 +83,13 @@ public interface Plugin {
State getState();
/**
* Returns an integer code indicating why the plugin is
* {@link State#DISABLED disabled}, or -1 if the plugin is not disabled.
* Returns a set of flags indicating why the plugin is
* {@link State#DISABLED disabled}, or 0 if the plugin is not disabled.
* <p>
* The codes used are plugin-specific, except the generic codes
* {@link #REASON_STARTING_STOPPING} and {@link #REASON_USER}, which may
* be used by any plugin.
* The flags used are plugin-specific, except the generic flag
* {@link #REASON_USER}, which may be used by any plugin.
*/
int getReasonDisabled();
int getReasonsDisabled();
/**
* 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
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_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 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.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.logException;
import static org.briarproject.bramble.util.LogUtils.now;
@@ -277,7 +277,7 @@ class PluginManagerImpl implements PluginManager, Service {
private final TransportId id;
private final AtomicReference<State> state =
new AtomicReference<>(DISABLED);
new AtomicReference<>(STARTING_STOPPING);
private Callback(TransportId 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.PROP_ADDRESS;
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.Plugin.State.ACTIVE;
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.STARTING_STOPPING;
import static org.briarproject.bramble.util.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubMacAddress;
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
@@ -163,16 +163,15 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
@Override
public void start() throws PluginException {
if (used.getAndSet(true)) throw new IllegalStateException();
try {
initialiseAdapter();
} catch (IOException e) {
state.setNoAdapter();
throw new PluginException(e);
}
updateProperties();
Settings settings = callback.getSettings();
boolean enabledByUser = settings.getBoolean(PREF_PLUGIN_ENABLE, false);
state.setStarted(enabledByUser);
try {
initialiseAdapter();
} catch (IOException e) {
throw new PluginException(e);
}
updateProperties();
if (enabledByUser) {
if (isAdapterEnabled()) bind();
else enableAdapter();
@@ -256,8 +255,8 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
}
@Override
public int getReasonDisabled() {
return state.getReasonDisabled();
public int getReasonsDisabled() {
return state.getReasonsDisabled();
}
@Override
@@ -477,7 +476,6 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
@GuardedBy("this")
private boolean started = false,
stopped = false,
noAdapter = false,
enabledByUser = false;
@GuardedBy("this")
@@ -499,11 +497,6 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
return ss;
}
synchronized void setNoAdapter() {
noAdapter = true;
callback.pluginStateChanged(getState());
}
@Nullable
synchronized SS setEnabledByUser(boolean enabledByUser) {
this.enabledByUser = enabledByUser;
@@ -532,14 +525,13 @@ abstract class BluetoothPlugin<SS> implements DuplexPlugin, EventListener {
}
synchronized State getState() {
if (!started || stopped || !enabledByUser) return DISABLED;
if (!started || stopped) return STARTING_STOPPING;
if (!enabledByUser) return DISABLED;
return serverSocket == null ? INACTIVE : ACTIVE;
}
synchronized int getReasonDisabled() {
if (noAdapter && !stopped) return REASON_NO_BT_ADAPTER;
if (!started || stopped) return REASON_STARTING_STOPPING;
return enabledByUser ? -1 : REASON_USER;
synchronized int getReasonsDisabled() {
return getState() == DISABLED ? REASON_USER : 0;
}
}
}

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.DISABLED;
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.LogUtils.logException;
import static org.briarproject.bramble.util.PrivacyUtils.scrubSocketAddress;
@@ -205,8 +206,8 @@ abstract class TcpPlugin implements DuplexPlugin, EventListener {
}
@Override
public int getReasonDisabled() {
return state.getReasonDisabled();
public int getReasonsDisabled() {
return state.getReasonsDisabled();
}
@Override
@@ -455,13 +456,13 @@ abstract class TcpPlugin implements DuplexPlugin, EventListener {
}
synchronized State getState() {
if (!started || stopped || !enabledByUser) return DISABLED;
if (!started || stopped) return STARTING_STOPPING;
if (!enabledByUser) return DISABLED;
return serverSocket == null ? INACTIVE : ACTIVE;
}
synchronized int getReasonDisabled() {
if (!started || stopped) return REASON_STARTING_STOPPING;
return enabledByUser ? -1 : REASON_USER;
synchronized int getReasonsDisabled() {
return getState() == DISABLED ? REASON_USER : 0;
}
}
}

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.ENABLING;
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.ID;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_MOBILE;
@@ -533,8 +534,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
}
@Override
public int getReasonDisabled() {
return state.getReasonDisabled();
public int getReasonsDisabled() {
return state.getReasonsDisabled();
}
@Override
@@ -773,7 +774,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
String country = locationUtils.getCurrentCountry();
boolean blocked =
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,
PREF_TOR_NETWORK_AUTOMATIC);
boolean useMobile = settings.getBoolean(PREF_TOR_MOBILE, true);
@@ -789,29 +791,32 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
LOG.info("Charging: " + charging);
}
int reasonsDisabled = 0;
boolean enableNetwork = false, enableBridges = false;
boolean useMeek = false, enableConnectionPadding = false;
boolean disabledBySettings = false;
int reasonDisabled = REASON_STARTING_STOPPING;
if (!online) {
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 {
if (!enabledByUser) {
LOG.info("User has disabled Tor");
reasonsDisabled |= REASON_USER;
}
if (!charging && onlyWhenCharging) {
LOG.info("Configured not to use battery");
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 {
LOG.info("Enabling network");
enableNetwork = true;
@@ -835,8 +840,9 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
LOG.info("Disabling connection padding");
}
}
}
state.setDisabledBySettings(disabledBySettings, reasonDisabled);
state.setReasonsDisabled(reasonsDisabled);
try {
if (enableNetwork) {
@@ -865,11 +871,10 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
networkEnabled = false,
bootstrapped = false,
circuitBuilt = false,
settingsChecked = false,
disabledBySettings = false;
settingsChecked = false;
@GuardedBy("this")
private int reasonDisabled = REASON_STARTING_STOPPING;
private int reasonsDisabled = 0;
@GuardedBy("this")
@Nullable
@@ -912,11 +917,9 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
callback.pluginStateChanged(getState());
}
synchronized void setDisabledBySettings(boolean disabledBySettings,
int reasonDisabled) {
synchronized void setReasonsDisabled(int reasonsDisabled) {
settingsChecked = true;
this.disabledBySettings = disabledBySettings;
this.reasonDisabled = reasonDisabled;
this.reasonsDisabled = reasonsDisabled;
callback.pluginStateChanged(getState());
}
@@ -933,16 +936,17 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
}
synchronized State getState() {
if (!started || stopped || !settingsChecked || disabledBySettings) {
return DISABLED;
if (!started || stopped || !settingsChecked) {
return STARTING_STOPPING;
}
if (reasonsDisabled != 0) return DISABLED;
if (!networkInitialised) return ENABLING;
if (!networkEnabled) return INACTIVE;
return bootstrapped && circuitBuilt ? ACTIVE : ENABLING;
}
synchronized int getReasonDisabled() {
return getState() == DISABLED ? reasonDisabled : -1;
synchronized int getReasonsDisabled() {
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.Logger.getLogger;
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.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.StringUtils.isNullOrEmpty;
@@ -121,8 +121,8 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
}
@Override
public int getReasonDisabled() {
return getState() == DISABLED ? REASON_STARTING_STOPPING : -1;
public int getReasonsDisabled() {
return 0;
}
@Override
@@ -280,7 +280,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
}
private State getState() {
if (!started || stopped) return DISABLED;
if (!started || stopped) return STARTING_STOPPING;
if (failed) return INACTIVE;
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.DISABLED;
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_PERMISSION_CAMERA_LOCATION;
@@ -258,7 +259,9 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
private boolean shouldEnableWifi() {
if (hasEnabledWifi) return false;
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() {
@@ -284,7 +287,9 @@ public abstract class KeyAgreementActivity extends BriarActivity implements
if (bluetoothDecision != BluetoothDecision.ACCEPTED) return false;
if (hasEnabledBluetooth) return false;
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

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.WARNING;
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.briar.android.TestingConstants.EXPIRY_DATE;
import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
@@ -194,7 +194,7 @@ public class NavDrawerViewModel extends AndroidViewModel
private State getTransportState(TransportId id) {
Plugin plugin = pluginManager.getPlugin(id);
return plugin == null ? DISABLED : plugin.getState();
return plugin == null ? STARTING_STOPPING : plugin.getState();
}
@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.DISABLED;
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;
class PluginViewController {
@@ -38,10 +39,13 @@ class PluginViewController {
for (TransportId t : TRANSPORT_IDS) {
// a OnCheckedChangeListener would get triggered on programmatic updates
SwitchCompat switchCompat = getSwitch(t);
switchCompat.setOnClickListener(buttonView ->
switchCompat.setOnClickListener(buttonView -> {
// 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)
.observe(owner, state -> stateUpdate(t, state));
}
@@ -60,7 +64,9 @@ class PluginViewController {
}
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) {