diff --git a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java index 7ccaa9a2797a4a96b92429996553be31f5f3e252..73b2a39b39657d4ddc4b336c9ca87d1cd69901be 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/plugin/tor/TorPlugin.java @@ -16,6 +16,7 @@ import android.os.PowerManager; import net.freehaven.tor.control.EventHandler; import net.freehaven.tor.control.TorControlConnection; +import org.briarproject.bramble.PoliteExecutor; import org.briarproject.bramble.api.contact.ContactId; import org.briarproject.bramble.api.data.BdfList; import org.briarproject.bramble.api.event.Event; @@ -63,8 +64,6 @@ import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; import java.util.logging.Logger; import java.util.regex.Pattern; import java.util.zip.ZipInputStream; @@ -111,7 +110,7 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { private static final Logger LOG = Logger.getLogger(TorPlugin.class.getName()); - private final Executor ioExecutor; + private final Executor ioExecutor, connectionStatusExecutor; private final ScheduledExecutorService scheduler; private final Context appContext; private final LocationUtils locationUtils; @@ -125,7 +124,6 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { private final File torDirectory, torFile, geoIpFile, configFile; private final File doneFile, cookieFile; private final PowerManager.WakeLock wakeLock; - private final Lock connectionStatusLock; private final AtomicReference<Future<?>> connectivityCheck = new AtomicReference<>(); private final AtomicBoolean used = new AtomicBoolean(false); @@ -167,7 +165,9 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { // This tag will prevent Huawei's powermanager from killing us. wakeLock = pm.newWakeLock(PARTIAL_WAKE_LOCK, "LocationManagerService"); wakeLock.setReferenceCounted(false); - connectionStatusLock = new ReentrantLock(); + // Don't execute more than one connection status check at a time + connectionStatusExecutor = new PoliteExecutor("TorPlugin", + ioExecutor, 1); } @Override @@ -697,54 +697,44 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener { } private void updateConnectionStatus() { - ioExecutor.execute(() -> { + connectionStatusExecutor.execute(() -> { if (!running) return; - try { - connectionStatusLock.lock(); - updateConnectionStatusLocked(); - } finally { - connectionStatusLock.unlock(); - } - }); - } + Object o = appContext.getSystemService(CONNECTIVITY_SERVICE); + ConnectivityManager cm = (ConnectivityManager) o; + NetworkInfo net = cm.getActiveNetworkInfo(); + boolean online = net != null && net.isConnected(); + boolean wifi = online && net.getType() == TYPE_WIFI; + String country = locationUtils.getCurrentCountry(); + boolean blocked = TorNetworkMetadata.isTorProbablyBlocked( + country); + Settings s = callback.getSettings(); + int network = s.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_ALWAYS); - // Locking: connectionStatusLock - private void updateConnectionStatusLocked() { - Object o = appContext.getSystemService(CONNECTIVITY_SERVICE); - ConnectivityManager cm = (ConnectivityManager) o; - NetworkInfo net = cm.getActiveNetworkInfo(); - boolean online = net != null && net.isConnected(); - boolean wifi = online && net.getType() == TYPE_WIFI; - String country = locationUtils.getCurrentCountry(); - boolean blocked = TorNetworkMetadata.isTorProbablyBlocked( - country); - Settings s = callback.getSettings(); - int network = s.getInt(PREF_TOR_NETWORK, PREF_TOR_NETWORK_ALWAYS); - - if (LOG.isLoggable(INFO)) { - LOG.info("Online: " + online + ", wifi: " + wifi); - if ("".equals(country)) LOG.info("Country code unknown"); - else LOG.info("Country code: " + country); - } + if (LOG.isLoggable(INFO)) { + LOG.info("Online: " + online + ", wifi: " + wifi); + if ("".equals(country)) LOG.info("Country code unknown"); + else LOG.info("Country code: " + country); + } - try { - if (!online) { - LOG.info("Disabling network, device is offline"); - enableNetwork(false); - } else if (blocked) { - LOG.info("Disabling network, country is blocked"); - enableNetwork(false); - } else if (network == PREF_TOR_NETWORK_NEVER - || (network == PREF_TOR_NETWORK_WIFI && !wifi)) { - LOG.info("Disabling network due to data setting"); - enableNetwork(false); - } else { - LOG.info("Enabling network"); - enableNetwork(true); + try { + if (!online) { + LOG.info("Disabling network, device is offline"); + enableNetwork(false); + } else if (blocked) { + LOG.info("Disabling network, country is blocked"); + enableNetwork(false); + } else if (network == PREF_TOR_NETWORK_NEVER + || (network == PREF_TOR_NETWORK_WIFI && !wifi)) { + LOG.info("Disabling network due to data setting"); + enableNetwork(false); + } else { + LOG.info("Enabling network"); + enableNetwork(true); + } + } catch (IOException e) { + if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); } - } catch (IOException e) { - if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); - } + }); } private void scheduleConnectionStatusUpdate() {