diff --git a/bramble-android/src/main/java/org/briarproject/bramble/battery/AndroidBatteryManager.java b/bramble-android/src/main/java/org/briarproject/bramble/battery/AndroidBatteryManager.java index 3b8250dad..0bd13b0b2 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/battery/AndroidBatteryManager.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/battery/AndroidBatteryManager.java @@ -19,9 +19,7 @@ import javax.inject.Inject; import static android.content.Intent.ACTION_BATTERY_CHANGED; import static android.content.Intent.ACTION_POWER_CONNECTED; import static android.content.Intent.ACTION_POWER_DISCONNECTED; -import static android.os.BatteryManager.BATTERY_STATUS_CHARGING; -import static android.os.BatteryManager.BATTERY_STATUS_FULL; -import static android.os.BatteryManager.EXTRA_STATUS; +import static android.os.BatteryManager.EXTRA_PLUGGED; import static java.util.logging.Level.INFO; import static java.util.logging.Logger.getLogger; @@ -48,9 +46,8 @@ class AndroidBatteryManager implements BatteryManager, Service { IntentFilter filter = new IntentFilter(ACTION_BATTERY_CHANGED); Intent i = appContext.registerReceiver(null, filter); if (i == null) return false; - int status = i.getIntExtra(EXTRA_STATUS, -1); - return status == BATTERY_STATUS_CHARGING || - status == BATTERY_STATUS_FULL; + int status = i.getIntExtra(EXTRA_PLUGGED, 0); + return status != 0; } @Override diff --git a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TorConstants.java b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TorConstants.java index d3f863c6b..6be7582a1 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TorConstants.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/api/plugin/TorConstants.java @@ -16,6 +16,7 @@ public interface TorConstants { String PREF_TOR_NETWORK = "network2"; String PREF_TOR_PORT = "port"; String PREF_TOR_MOBILE = "useMobileData"; + String PREF_TOR_ONLY_WHEN_CHARGING = "onlyWhenCharging"; int PREF_TOR_NETWORK_AUTOMATIC = 0; int PREF_TOR_NETWORK_WITHOUT_BRIDGES = 1; diff --git a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java index 46770b884..d672b4cb4 100644 --- a/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java +++ b/bramble-core/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java @@ -69,6 +69,7 @@ import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_AUTOMATIC; import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_NETWORK_NEVER; 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.api.plugin.TorConstants.PREF_TOR_PORT; import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION_V2; import static org.briarproject.bramble.api.plugin.TorConstants.PROP_ONION_V3; @@ -648,8 +649,10 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener { if (s.getNamespace().equals(ID.getString())) { LOG.info("Tor settings updated"); settings = s.getSettings(); - // Works around a bug introduced in Tor 0.3.4.8. Could be - // replaced with callback.transportDisabled() when fixed. + // Works around a bug introduced in Tor 0.3.4.8. + // https://trac.torproject.org/projects/tor/ticket/28027 + // Could be replaced with callback.transportDisabled() + // when fixed. disableNetwork(); updateConnectionStatus(networkManager.getNetworkStatus(), batteryManager.isCharging()); @@ -685,6 +688,8 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener { int network = settings.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_AUTOMATIC); boolean useMobile = settings.getBoolean(PREF_TOR_MOBILE, true); + boolean onlyWhenCharging = + settings.getBoolean(PREF_TOR_ONLY_WHEN_CHARGING, false); boolean bridgesWork = circumventionProvider.doBridgesWork(country); boolean automatic = network == PREF_TOR_NETWORK_AUTOMATIC; @@ -699,9 +704,12 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener { if (!online) { LOG.info("Disabling network, device is offline"); enableNetwork(false); + } else if (!charging && onlyWhenCharging) { + LOG.info("Disabling network, device is on battery"); + enableNetwork(false); } else if (network == PREF_TOR_NETWORK_NEVER || (!useMobile && !wifi)) { - LOG.info("Disabling network due to setting"); + LOG.info("Disabling network, device is using mobile data"); enableNetwork(false); } else if (automatic && blocked && !bridgesWork) { LOG.info("Disabling network, country is blocked"); 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 6f4e053be..1be93ebce 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 @@ -75,6 +75,7 @@ import static org.briarproject.bramble.api.plugin.BluetoothConstants.PREF_BT_ENA 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_AUTOMATIC; +import static org.briarproject.bramble.api.plugin.TorConstants.PREF_TOR_ONLY_WHEN_CHARGING; import static org.briarproject.bramble.util.LogUtils.logDuration; import static org.briarproject.bramble.util.LogUtils.logException; import static org.briarproject.bramble.util.LogUtils.now; @@ -111,6 +112,8 @@ public class SettingsFragment extends PreferenceFragmentCompat public static final String NOTIFY_SIGN_IN = "pref_key_notify_sign_in"; public static final String TOR_NETWORK = "pref_key_tor_network"; public static final String TOR_MOBILE = "pref_key_tor_mobile_data"; + public static final String TOR_ONLY_WHEN_CHARGING = + "pref_key_tor_only_when_charging"; private static final Logger LOG = Logger.getLogger(SettingsFragment.class.getName()); @@ -120,6 +123,7 @@ public class SettingsFragment extends PreferenceFragmentCompat private ListPreference enableBluetooth; private ListPreference torNetwork; private SwitchPreference torMobile; + private SwitchPreference torOnlyWhenCharging; private SwitchPreference screenLock; private ListPreference screenLockTimeout; private SwitchPreference notifyPrivateMessages; @@ -165,6 +169,8 @@ public class SettingsFragment extends PreferenceFragmentCompat enableBluetooth = (ListPreference) findPreference("pref_key_bluetooth"); torNetwork = (ListPreference) findPreference(TOR_NETWORK); torMobile = (SwitchPreference) findPreference(TOR_MOBILE); + torOnlyWhenCharging = + (SwitchPreference) findPreference(TOR_ONLY_WHEN_CHARGING); screenLock = (SwitchPreference) findPreference(PREF_SCREEN_LOCK); screenLockTimeout = (ListPreference) findPreference(PREF_SCREEN_LOCK_TIMEOUT); @@ -202,6 +208,7 @@ public class SettingsFragment extends PreferenceFragmentCompat enableBluetooth.setOnPreferenceChangeListener(this); torNetwork.setOnPreferenceChangeListener(this); torMobile.setOnPreferenceChangeListener(this); + torOnlyWhenCharging.setOnPreferenceChangeListener(this); screenLock.setOnPreferenceChangeListener(this); screenLockTimeout.setOnPreferenceChangeListener(this); @@ -362,6 +369,10 @@ public class SettingsFragment extends PreferenceFragmentCompat torSettings.getBoolean(PREF_TOR_MOBILE, true); torMobile.setChecked(torMobileSetting); + boolean torChargingSetting = + torSettings.getBoolean(PREF_TOR_ONLY_WHEN_CHARGING, false); + torOnlyWhenCharging.setChecked(torChargingSetting); + displayScreenLockSetting(); if (SDK_INT < 26) { @@ -423,6 +434,7 @@ public class SettingsFragment extends PreferenceFragmentCompat enableBluetooth.setEnabled(enabled); torNetwork.setEnabled(enabled); torMobile.setEnabled(enabled); + torOnlyWhenCharging.setEnabled(enabled); if (!enabled) screenLock.setEnabled(false); notifyPrivateMessages.setEnabled(enabled); notifyGroupMessages.setEnabled(enabled); @@ -519,6 +531,9 @@ public class SettingsFragment extends PreferenceFragmentCompat } else if (preference == torMobile) { boolean torMobileSetting = (Boolean) newValue; storeTorMobileSetting(torMobileSetting); + } else if (preference == torOnlyWhenCharging) { + boolean torChargingSetting = (Boolean) newValue; + storeTorChargingSetting(torChargingSetting); } else if (preference == screenLock) { Settings s = new Settings(); s.putBoolean(PREF_SCREEN_LOCK, (Boolean) newValue); @@ -585,6 +600,12 @@ public class SettingsFragment extends PreferenceFragmentCompat mergeSettings(s, TOR_NAMESPACE); } + private void storeTorChargingSetting(boolean torChargingSetting) { + Settings s = new Settings(); + s.putBoolean(PREF_TOR_ONLY_WHEN_CHARGING, torChargingSetting); + mergeSettings(s, TOR_NAMESPACE); + } + private void storeBluetoothSettings(boolean btSetting) { Settings s = new Settings(); s.putBoolean(PREF_BT_ENABLE, btSetting); diff --git a/briar-android/src/main/res/values/strings.xml b/briar-android/src/main/res/values/strings.xml index 4e4e6c6b2..762a29427 100644 --- a/briar-android/src/main/res/values/strings.xml +++ b/briar-android/src/main/res/values/strings.xml @@ -380,6 +380,8 @@ Automatic: %1$s (in %2$s) Use mobile data + Connect via Internet (Tor) only when charging + Disables Internet connection when device is running on battery Security diff --git a/briar-android/src/main/res/xml/settings.xml b/briar-android/src/main/res/xml/settings.xml index 1ed3c3630..d45a80f86 100644 --- a/briar-android/src/main/res/xml/settings.xml +++ b/briar-android/src/main/res/xml/settings.xml @@ -57,6 +57,15 @@ android:widgetLayout="@layout/preference_switch_compat" app:iconSpaceReserved="false"/> + +