From d689cf776c769fd8f8c3e006f2a09a7112f80b9b Mon Sep 17 00:00:00 2001 From: akwizgran Date: Thu, 6 Feb 2020 13:38:48 +0000 Subject: [PATCH] Change Tor settings after asking for confirmation. --- .../plugin/tor/CircumventionProvider.java | 2 +- .../android/navdrawer/NavDrawerActivity.java | 49 ++++++++++++++++++- .../android/navdrawer/NavDrawerViewModel.java | 28 +++++++++++ .../navdrawer/PluginViewController.java | 28 ++++++++++- .../android/settings/SettingsFragment.java | 10 ++-- .../briar/android/util/UiUtils.java | 12 +++++ briar-android/src/main/res/values/strings.xml | 5 ++ 7 files changed, 123 insertions(+), 11 deletions(-) diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/CircumventionProvider.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/CircumventionProvider.java index 1e670de96..944399799 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/CircumventionProvider.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/CircumventionProvider.java @@ -17,7 +17,7 @@ public interface CircumventionProvider { 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}. */ String[] BRIDGES = { "CN", "IR", "EG", "BY", "TR", "SY", "VE" }; diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java index d1a5ea458..91b2e147c 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerActivity.java @@ -17,6 +17,7 @@ import org.briarproject.bramble.api.db.DbException; import org.briarproject.bramble.api.lifecycle.LifecycleManager; import org.briarproject.bramble.api.nullsafety.MethodsNotNullByDefault; import org.briarproject.bramble.api.nullsafety.ParametersNotNullByDefault; +import org.briarproject.bramble.api.system.LocationUtils; import org.briarproject.briar.R; import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.BriarActivity; @@ -37,6 +38,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.ActionBarDrawerToggle; +import androidx.appcompat.app.AlertDialog; import androidx.appcompat.widget.Toolbar; import androidx.core.app.ActivityCompat; 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.logging.Logger.getLogger; 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.activity.RequestCodes.REQUEST_PASSWORD; 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; @MethodsNotNullByDefault @@ -84,9 +90,13 @@ public class NavDrawerActivity extends BriarActivity implements @Inject ViewModelProvider.Factory viewModelFactory; + @Inject LifecycleManager lifecycleManager; + @Inject + LocationUtils locationUtils; + private DrawerLayout drawerLayout; private NavigationView navigation; @@ -110,7 +120,10 @@ public class NavDrawerActivity extends BriarActivity implements }); 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); 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(); + } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerViewModel.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerViewModel.java index da95ef228..8f1909541 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerViewModel.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/NavDrawerViewModel.java @@ -34,7 +34,12 @@ 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.PREF_PLUGIN_ENABLE; 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.briar.android.TestingConstants.EXPIRY_DATE; import static org.briarproject.briar.android.TestingConstants.IS_DEBUG_BUILD; @@ -216,8 +221,31 @@ public class NavDrawerViewModel extends AndroidViewModel return liveData; } + int getReasonsDisabled(TransportId id) { + Plugin plugin = pluginManager.getPlugin(id); + return plugin == null ? 0 : plugin.getReasonsDisabled(); + } + void setPluginEnabled(TransportId t, boolean 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); + } + }); + } + } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewController.java b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewController.java index f8776e566..ea3de6d2d 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewController.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/navdrawer/PluginViewController.java @@ -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.TransportId; 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.SwitchCompat; @@ -21,6 +23,7 @@ import static android.os.Build.VERSION.SDK_INT; import static android.transition.TransitionManager.beginDelayedTransition; import static android.view.View.FOCUS_DOWN; 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.DISABLED; 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 { + private final NavDrawerViewModel viewModel; private final ConstraintLayout drawerContent; private final ConstraintSet collapsedConstraints, expandedConstraints; private final AppCompatImageButton chevronView; private final ImageView torIcon, wifiIcon, btIcon; private final SwitchCompat torSwitch, wifiSwitch, btSwitch; + private final MutableLiveEvent reasonsTorDisabled = + new MutableLiveEvent<>(); private boolean expanded = false; PluginViewController(View v, LifecycleOwner owner, NavDrawerViewModel viewModel) { + this.viewModel = viewModel; drawerContent = v.findViewById(R.id.drawerContent); collapsedConstraints = new ConstraintSet(); @@ -75,8 +82,8 @@ class PluginViewController { // a OnCheckedChangeListener would get triggered on programmatic updates SwitchCompat switchCompat = getSwitch(t); switchCompat.setOnClickListener(buttonView -> { - // TODO check reason first and change settings if needed - viewModel.setPluginEnabled(t, switchCompat.isChecked()); + if (switchCompat.isChecked()) tryToEnablePlugin(t); + else viewModel.setPluginEnabled(t, false); // Revert the switch to its previous state until the plugin // changes its state switchCompat.toggle(); @@ -98,6 +105,23 @@ class PluginViewController { expanded = !expanded; } + LiveEvent 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) { updateIcon(getIcon(id), state); updateSwitch(getSwitch(id), state); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java b/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java index 9d1d8da7f..07dd5a327 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/settings/SettingsFragment.java @@ -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.activity.RequestCodes.REQUEST_RINGTONE; 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.triggerFeedback; 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 String country = locationUtils.getCurrentCountry(); - String countryName = country; - for (Locale locale : Locale.getAvailableLocales()) { - if (locale.getCountry().equalsIgnoreCase(country)) { - countryName = locale.getDisplayCountry(); - break; - } - } + String countryName = getCountryDisplayName(country); + boolean blocked = circumventionProvider.isTorProbablyBlocked(country); boolean useBridges = circumventionProvider.doBridgesWork(country); diff --git a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java index f4bdb966a..6e849600e 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/util/UiUtils.java @@ -38,6 +38,8 @@ import org.briarproject.briar.R; import org.briarproject.briar.android.view.ArticleMovementMethod; import org.briarproject.briar.android.widget.LinkDialogFragment; +import java.util.Locale; + import androidx.annotation.AttrRes; import androidx.annotation.ColorInt; import androidx.annotation.ColorRes; @@ -401,4 +403,14 @@ public class UiUtils { return ctx.getResources().getConfiguration().getLayoutDirection() == 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; + } } diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index 44383379a..504ea3e1b 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -569,6 +569,11 @@ Briar is locked Tap to unlock + + Turning on Tor will change the following settings:\n\n%1$s + Don\'t use mobile data + Don\'t connect to Internet (Tor) in %1$s +