Change Tor settings after asking for confirmation.

This commit is contained in:
akwizgran
2020-02-06 13:38:48 +00:00
parent 0664720680
commit 02b4925609
7 changed files with 122 additions and 11 deletions

View File

@@ -17,7 +17,7 @@ public interface CircumventionProvider {
String[] BLOCKED = {"CN", "IR", "EG", "BY", "TR", "SY", "VE"}; String[] BLOCKED = {"CN", "IR", "EG", "BY", "TR", "SY", "VE"};
/** /**
* Countries where obfs4 bridge connection are likely to work. * Countries where obfs4 or meek bridge connections are likely to work.
* Should be a subset of {@link #BLOCKED}. * Should be a subset of {@link #BLOCKED}.
*/ */
String[] BRIDGES = { "CN", "IR", "EG", "BY", "TR", "SY", "VE" }; String[] BRIDGES = { "CN", "IR", "EG", "BY", "TR", "SY", "VE" };

View File

@@ -17,6 +17,7 @@ import org.briarproject.bramble.api.db.DbException;
import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.lifecycle.LifecycleManager;
import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault;
import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault;
import org.briarproject.bramble.api.system.LocationUtils;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.ActivityComponent;
import org.briarproject.briar.android.activity.BriarActivity; import org.briarproject.briar.android.activity.BriarActivity;
@@ -37,6 +38,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.ActionBarDrawerToggle; import androidx.appcompat.app.ActionBarDrawerToggle;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.widget.Toolbar; import androidx.appcompat.widget.Toolbar;
import androidx.core.app.ActivityCompat; import androidx.core.app.ActivityCompat;
import androidx.drawerlayout.widget.DrawerLayout; import androidx.drawerlayout.widget.DrawerLayout;
@@ -53,9 +55,13 @@ import static androidx.fragment.app.FragmentManager.POP_BACK_STACK_INCLUSIVE;
import static java.util.Objects.requireNonNull; import static java.util.Objects.requireNonNull;
import static java.util.logging.Logger.getLogger; import static java.util.logging.Logger.getLogger;
import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING; import static org.briarproject.bramble.api.lifecycle.LifecycleManager.LifecycleState.RUNNING;
import static org.briarproject.bramble.api.plugin.TorConstants.REASON_BATTERY;
import static org.briarproject.bramble.api.plugin.TorConstants.REASON_COUNTRY_BLOCKED;
import static org.briarproject.bramble.api.plugin.TorConstants.REASON_MOBILE_DATA;
import static org.briarproject.briar.android.BriarService.EXTRA_STARTUP_FAILED; import static org.briarproject.briar.android.BriarService.EXTRA_STARTUP_FAILED;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PASSWORD; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PASSWORD;
import static org.briarproject.briar.android.navdrawer.IntentRouter.handleExternalIntent; import static org.briarproject.briar.android.navdrawer.IntentRouter.handleExternalIntent;
import static org.briarproject.briar.android.util.UiUtils.getCountryDisplayName;
import static org.briarproject.briar.android.util.UiUtils.getDaysUntilExpiry; import static org.briarproject.briar.android.util.UiUtils.getDaysUntilExpiry;
@MethodsNotNullByDefault @MethodsNotNullByDefault
@@ -84,9 +90,13 @@ public class NavDrawerActivity extends BriarActivity implements
@Inject @Inject
ViewModelProvider.Factory viewModelFactory; ViewModelProvider.Factory viewModelFactory;
@Inject @Inject
LifecycleManager lifecycleManager; LifecycleManager lifecycleManager;
@Inject
LocationUtils locationUtils;
private DrawerLayout drawerLayout; private DrawerLayout drawerLayout;
private NavigationView navigation; private NavigationView navigation;
@@ -110,7 +120,10 @@ public class NavDrawerActivity extends BriarActivity implements
}); });
View drawerScrollView = findViewById(R.id.drawerScrollView); View drawerScrollView = findViewById(R.id.drawerScrollView);
new PluginViewController(drawerScrollView, this, viewModel); PluginViewController pluginViewController =
new PluginViewController(drawerScrollView, this, viewModel);
pluginViewController.getReasonsTorDisabled().observeEvent(this,
this::showTorSettingsDialog);
Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar);
drawerLayout = findViewById(R.id.drawer_layout); drawerLayout = findViewById(R.id.drawer_layout);
@@ -350,4 +363,38 @@ public class NavDrawerActivity extends BriarActivity implements
} }
} }
private void showTorSettingsDialog(int reasonsDisabled) {
boolean battery = (reasonsDisabled & REASON_BATTERY) != 0;
boolean mobileData = (reasonsDisabled & REASON_MOBILE_DATA) != 0;
boolean location = (reasonsDisabled & REASON_COUNTRY_BLOCKED) != 0;
StringBuilder s = new StringBuilder();
if (location) {
s.append("\t\u2022 ");
s.append(getString(R.string.tor_override_network_setting,
getCountryDisplayName(locationUtils.getCurrentCountry())));
s.append('\n');
}
if (mobileData) {
s.append("\t\u2022 ");
s.append(getString(R.string.tor_override_mobile_data_setting));
s.append('\n');
}
if (battery) {
s.append("\t\u2022 ");
s.append(getString(R.string.tor_only_when_charging_title));
s.append('\n');
}
String message =
getString(R.string.tor_override_settings_body, s.toString());
AlertDialog.Builder b =
new AlertDialog.Builder(this, R.style.BriarDialogTheme);
b.setMessage(message);
b.setPositiveButton(R.string.continue_button, (dialog, which) ->
viewModel.setTorEnabled(battery, mobileData, location));
b.setNegativeButton(R.string.cancel, (dialog, which) ->
dialog.dismiss());
b.show();
}
} }

View File

@@ -34,7 +34,12 @@ 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.PREF_PLUGIN_ENABLE;
import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING; import static org.briarproject.bramble.api.plugin.Plugin.State.STARTING_STOPPING;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_MOBILE;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_WITH_BRIDGES;
import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_ONLY_WHEN_CHARGING;
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;
@@ -216,8 +221,31 @@ public class NavDrawerViewModel extends AndroidViewModel
return liveData; return liveData;
} }
int getReasonsDisabled(TransportId id) {
Plugin plugin = pluginManager.getPlugin(id);
return plugin == null ? 0 : plugin.getReasonsDisabled();
}
void setPluginEnabled(TransportId t, boolean enabled) { void setPluginEnabled(TransportId t, boolean enabled) {
pluginManager.setPluginEnabled(t, enabled); pluginManager.setPluginEnabled(t, enabled);
} }
void setTorEnabled(boolean battery, boolean mobileData, boolean location) {
Plugin plugin = pluginManager.getPlugin(TorConstants.ID);
if (plugin == null) return;
Settings s = new Settings();
s.putBoolean(PREF_PLUGIN_ENABLE, true);
if (battery) s.putBoolean(PREF_TOR_ONLY_WHEN_CHARGING, false);
if (mobileData) s.putBoolean(PREF_TOR_MOBILE, true);
if (location) s.putInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_WITH_BRIDGES);
dbExecutor.execute(() -> {
try {
settingsManager.mergeSettings(s, TorConstants.ID.getString());
} catch (DbException e) {
logException(LOG, WARNING, e);
}
});
}
} }

View File

@@ -10,6 +10,8 @@ import org.briarproject.bramble.api.plugin.Plugin.State;
import org.briarproject.bramble.api.plugin.TorConstants; import org.briarproject.bramble.api.plugin.TorConstants;
import org.briarproject.bramble.api.plugin.TransportId; import org.briarproject.bramble.api.plugin.TransportId;
import org.briarproject.briar.R; import org.briarproject.briar.R;
import org.briarproject.briar.android.viewmodel.LiveEvent;
import org.briarproject.briar.android.viewmodel.MutableLiveEvent;
import androidx.appcompat.widget.AppCompatImageButton; import androidx.appcompat.widget.AppCompatImageButton;
import androidx.appcompat.widget.SwitchCompat; import androidx.appcompat.widget.SwitchCompat;
@@ -21,6 +23,7 @@ import static android.os.Build.VERSION.SDK_INT;
import static android.transition.TransitionManager.beginDelayedTransition; import static android.transition.TransitionManager.beginDelayedTransition;
import static android.view.View.FOCUS_DOWN; import static android.view.View.FOCUS_DOWN;
import static androidx.core.content.ContextCompat.getColor; import static androidx.core.content.ContextCompat.getColor;
import static org.briarproject.bramble.api.plugin.Plugin.REASON_USER;
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;
@@ -29,16 +32,20 @@ import static org.briarproject.briar.android.navdrawer.NavDrawerViewModel.TRANSP
class PluginViewController { class PluginViewController {
private final NavDrawerViewModel viewModel;
private final ConstraintLayout drawerContent; private final ConstraintLayout drawerContent;
private final ConstraintSet collapsedConstraints, expandedConstraints; private final ConstraintSet collapsedConstraints, expandedConstraints;
private final AppCompatImageButton chevronView; private final AppCompatImageButton chevronView;
private final ImageView torIcon, wifiIcon, btIcon; private final ImageView torIcon, wifiIcon, btIcon;
private final SwitchCompat torSwitch, wifiSwitch, btSwitch; private final SwitchCompat torSwitch, wifiSwitch, btSwitch;
private final MutableLiveEvent<Integer> reasonsTorDisabled =
new MutableLiveEvent<>();
private boolean expanded = false; private boolean expanded = false;
PluginViewController(View v, LifecycleOwner owner, PluginViewController(View v, LifecycleOwner owner,
NavDrawerViewModel viewModel) { NavDrawerViewModel viewModel) {
this.viewModel = viewModel;
drawerContent = v.findViewById(R.id.drawerContent); drawerContent = v.findViewById(R.id.drawerContent);
collapsedConstraints = new ConstraintSet(); collapsedConstraints = new ConstraintSet();
@@ -75,8 +82,8 @@ class PluginViewController {
// 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 if (switchCompat.isChecked()) tryToEnablePlugin(t);
viewModel.setPluginEnabled(t, switchCompat.isChecked()); else viewModel.setPluginEnabled(t, false);
// Revert the switch to its previous state until the plugin // Revert the switch to its previous state until the plugin
// changes its state // changes its state
switchCompat.toggle(); switchCompat.toggle();
@@ -98,6 +105,23 @@ class PluginViewController {
expanded = !expanded; expanded = !expanded;
} }
LiveEvent<Integer> getReasonsTorDisabled() {
return reasonsTorDisabled;
}
private void tryToEnablePlugin(TransportId id) {
if (id.equals(TorConstants.ID)) {
int reasons = viewModel.getReasonsDisabled(id);
if (reasons == 0 || reasons == REASON_USER) {
viewModel.setPluginEnabled(id, true);
} else {
reasonsTorDisabled.setEvent(reasons);
}
} else {
viewModel.setPluginEnabled(id, true);
}
}
private void stateUpdate(TransportId id, State state) { private void stateUpdate(TransportId id, State state) {
updateIcon(getIcon(id), state); updateIcon(getIcon(id), state);
updateSwitch(getSwitch(id), state); updateSwitch(getSwitch(id), state);

View File

@@ -85,6 +85,7 @@ import static org.briarproject.briar.android.BriarApplication.ENTRY_ACTIVITY;
import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD; import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD;
import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_RINGTONE; import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_RINGTONE;
import static org.briarproject.briar.android.navdrawer.NavDrawerActivity.SIGN_OUT_URI; import static org.briarproject.briar.android.navdrawer.NavDrawerActivity.SIGN_OUT_URI;
import static org.briarproject.briar.android.util.UiUtils.getCountryDisplayName;
import static org.briarproject.briar.android.util.UiUtils.hasScreenLock; import static org.briarproject.briar.android.util.UiUtils.hasScreenLock;
import static org.briarproject.briar.android.util.UiUtils.triggerFeedback; import static org.briarproject.briar.android.util.UiUtils.triggerFeedback;
import static org.briarproject.briar.api.android.AndroidNotificationManager.BLOG_CHANNEL_ID; import static org.briarproject.briar.api.android.AndroidNotificationManager.BLOG_CHANNEL_ID;
@@ -316,13 +317,8 @@ public class SettingsFragment extends PreferenceFragmentCompat
// Look up country name in the user's chosen language if available // Look up country name in the user's chosen language if available
String country = locationUtils.getCurrentCountry(); String country = locationUtils.getCurrentCountry();
String countryName = country; String countryName = getCountryDisplayName(country);
for (Locale locale : Locale.getAvailableLocales()) {
if (locale.getCountry().equalsIgnoreCase(country)) {
countryName = locale.getDisplayCountry();
break;
}
}
boolean blocked = boolean blocked =
circumventionProvider.isTorProbablyBlocked(country); circumventionProvider.isTorProbablyBlocked(country);
boolean useBridges = circumventionProvider.doBridgesWork(country); boolean useBridges = circumventionProvider.doBridgesWork(country);

View File

@@ -38,6 +38,8 @@ import org.briarproject.briar.R;
import org.briarproject.briar.android.view.ArticleMovementMethod; import org.briarproject.briar.android.view.ArticleMovementMethod;
import org.briarproject.briar.android.widget.LinkDialogFragment; import org.briarproject.briar.android.widget.LinkDialogFragment;
import java.util.Locale;
import androidx.annotation.AttrRes; import androidx.annotation.AttrRes;
import androidx.annotation.ColorInt; import androidx.annotation.ColorInt;
import androidx.annotation.ColorRes; import androidx.annotation.ColorRes;
@@ -402,4 +404,13 @@ public class UiUtils {
LAYOUT_DIRECTION_RTL; LAYOUT_DIRECTION_RTL;
} }
public static String getCountryDisplayName(String isoCode) {
for (Locale locale : Locale.getAvailableLocales()) {
if (locale.getCountry().equalsIgnoreCase(isoCode)) {
return locale.getDisplayCountry();
}
}
// Name is unknown
return isoCode;
}
} }

View File

@@ -567,6 +567,11 @@
<string name="lock_is_locked">Briar is locked</string> <string name="lock_is_locked">Briar is locked</string>
<string name="lock_tap_to_unlock">Tap to unlock</string> <string name="lock_tap_to_unlock">Tap to unlock</string>
<!-- Overriding Tor settings -->
<string name="tor_override_settings_body">Turning on Tor will change the following settings:\n\n%1$s</string>
<string name="tor_override_mobile_data_setting">Don\'t use mobile data</string>
<string name="tor_override_network_setting">Don\'t connect to Internet (Tor) in %1$s</string>
<!-- Screenshots --> <!-- Screenshots -->
<!-- This is a name to be used in screenshots. Feel free to change it to a local name. --> <!-- This is a name to be used in screenshots. Feel free to change it to a local name. -->