mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-18 13:49:53 +01:00
Made coding style consistent with rest of project.
This commit is contained in:
@@ -3,37 +3,16 @@ package org.briarproject.plugins.tor;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import org.briarproject.api.system.LocationUtils;
|
|
||||||
|
|
||||||
public class TorNetworkMetadata {
|
public class TorNetworkMetadata {
|
||||||
|
|
||||||
private static final Logger LOG =
|
// See https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
|
||||||
Logger.getLogger(TorNetworkMetadata.class.getName());
|
// and https://trac.torproject.org/projects/tor/wiki/doc/OONI/censorshipwiki
|
||||||
|
|
||||||
// for country codes see https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
|
|
||||||
// below list from https://trac.torproject.org/projects/tor/wiki/doc/OONI/censorshipwiki
|
|
||||||
// TODO: get a more complete list
|
// TODO: get a more complete list
|
||||||
public static final Set<String> BLOCKED_IN_COUNTRIES = new HashSet<String>(Arrays.asList(
|
private static final Set<String> BLOCKED_IN_COUNTRIES =
|
||||||
"CN",
|
new HashSet<String>(Arrays.asList("CN", "IR", "SY", "ZZ"));
|
||||||
"IR",
|
|
||||||
"SY",
|
|
||||||
//"ET", // possibly lifted - https://metrics.torproject.org/users.html?graph=userstats-relay-country&start=2012-02-08&end=2014-02-06&country=et&events=off#userstats-relay-country
|
|
||||||
//"KZ", // unclear due to botnet - https://metrics.torproject.org/users.html?graph=userstats-relay-country&start=2012-02-08&end=2014-02-06&country=kz&events=off#userstats-relay-country
|
|
||||||
//"PH", // unclear due to botnet - https://metrics.torproject.org/users.html?graph=userstats-relay-country&start=2012-02-08&end=2014-02-06&country=ph&events=off#userstats-relay-country
|
|
||||||
//"AE", // unclear due to botnet - https://metrics.torproject.org/users.html?graph=userstats-relay-country&start=2012-02-08&end=2014-02-06&country=ae&events=off#userstats-relay-country
|
|
||||||
//"GB", // for testing
|
|
||||||
"ZZ"
|
|
||||||
));
|
|
||||||
|
|
||||||
public static boolean isTorProbablyBlocked(LocationUtils locationUtils) {
|
public static boolean isTorProbablyBlocked(String countryCode) {
|
||||||
String countryCode = locationUtils.getCurrentCountry();
|
return BLOCKED_IN_COUNTRIES.contains(countryCode);
|
||||||
if (BLOCKED_IN_COUNTRIES.contains(countryCode)) {
|
|
||||||
LOG.info("Tor is probably blocked in your country: " + countryCode);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ import org.briarproject.api.plugins.duplex.DuplexPlugin;
|
|||||||
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
|
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
|
||||||
import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
|
import org.briarproject.api.plugins.duplex.DuplexPluginFactory;
|
||||||
import org.briarproject.api.system.LocationUtils;
|
import org.briarproject.api.system.LocationUtils;
|
||||||
import org.briarproject.plugins.AndroidPluginsModule;
|
|
||||||
import org.briarproject.plugins.tor.TorNetworkMetadata;
|
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
@@ -43,10 +41,14 @@ public class TorPluginFactory implements DuplexPluginFactory {
|
|||||||
|
|
||||||
public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
|
public DuplexPlugin createPlugin(DuplexPluginCallback callback) {
|
||||||
// Check that we have a Tor binary for this architecture
|
// Check that we have a Tor binary for this architecture
|
||||||
if(!Build.CPU_ABI.startsWith("armeabi")) return null;
|
if(!Build.CPU_ABI.startsWith("armeabi")) {
|
||||||
// Check that we don't know that Tor is blocked here
|
LOG.info("Tor is not supported on this architecture");
|
||||||
if (TorNetworkMetadata.isTorProbablyBlocked(locationUtils)) {
|
return null;
|
||||||
LOG.info("Tor has been pre-emptively disabled since it is probably blocked");
|
}
|
||||||
|
// Check whether we know that Tor is blocked in this country
|
||||||
|
String countryCode = locationUtils.getCurrentCountry();
|
||||||
|
if(TorNetworkMetadata.isTorProbablyBlocked(countryCode)) {
|
||||||
|
LOG.info("Tor has been disabled since it is probably blocked");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return new TorPlugin(pluginExecutor,appContext, shutdownManager,
|
return new TorPlugin(pluginExecutor,appContext, shutdownManager,
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package org.briarproject.system;
|
package org.briarproject.system;
|
||||||
|
|
||||||
|
import static android.content.Context.LOCATION_SERVICE;
|
||||||
|
import static android.content.Context.TELEPHONY_SERVICE;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@@ -25,11 +28,11 @@ class AndroidLocationUtils implements LocationUtils {
|
|||||||
private static final Logger LOG =
|
private static final Logger LOG =
|
||||||
Logger.getLogger(AndroidLocationUtils.class.getName());
|
Logger.getLogger(AndroidLocationUtils.class.getName());
|
||||||
|
|
||||||
final Context context;
|
private final Context ctx;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public AndroidLocationUtils(Context context) {
|
public AndroidLocationUtils(Context ctx) {
|
||||||
this.context = context;
|
this.ctx = ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -38,89 +41,86 @@ class AndroidLocationUtils implements LocationUtils {
|
|||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Phone network. This works even when no SIM card is inserted, or a
|
* <li>Phone network. This works even when no SIM card is inserted, or a
|
||||||
* foreign SIM card is inserted.</li>
|
* foreign SIM card is inserted.</li>
|
||||||
* <li><del>Location service (GPS/WiFi/etc).</del> <em>This is disabled for
|
* <li><del>Location service (GPS/WiFi/etc).</del> <em>This is disabled for
|
||||||
* now, until we figure out an offline method of converting a long/lat
|
* now, until we figure out an offline method of converting a long/lat
|
||||||
* into a country code, that doesn't involve a network call.</em>
|
* into a country code, that doesn't involve a network call.</em>
|
||||||
* <li>SIM card. This is only an heuristic and assumes the user is not
|
* <li>SIM card. This is only an heuristic and assumes the user is not
|
||||||
* roaming.</li>
|
* roaming.</li>
|
||||||
* <li>User Locale. This is an even worse heuristic.</li>
|
* <li>User locale. This is an even worse heuristic.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* Note: this is very similar to <a href="https://android.googlesource.com/platform/frameworks/base/+/cd92588%5E/location/java/android/location/CountryDetector.java">
|
* Note: this is very similar to <a href="https://android.googlesource.com/platform/frameworks/base/+/cd92588%5E/location/java/android/location/CountryDetector.java">
|
||||||
* this API</a> except it seems that Google doesn't want us to use it for
|
* this API</a> except it seems that Google doesn't want us to useit for
|
||||||
* some reason - both that class and {@code Context.COUNTRY_CODE} are
|
* some reason - both that class and {@code Context.COUNTRY_CODE} are
|
||||||
* annotated {@code @hide}.
|
* annotated {@code @hide}.
|
||||||
*/
|
*/
|
||||||
@SuppressLint("DefaultLocale")
|
@SuppressLint("DefaultLocale")
|
||||||
@Override
|
|
||||||
public String getCurrentCountry() {
|
public String getCurrentCountry() {
|
||||||
String countryCode;
|
String countryCode = getCountryFromPhoneNetwork();
|
||||||
countryCode = getCountryFromPhoneNetwork();
|
if(!TextUtils.isEmpty(countryCode)) return countryCode.toUpperCase();
|
||||||
if (!TextUtils.isEmpty(countryCode)) {
|
// Disabled because it involves a network call; requires
|
||||||
return countryCode.toUpperCase(); // android api gives lowercase for some reason
|
// ACCESS_FINE_LOCATION
|
||||||
}
|
// countryCode = getCountryFromLocation();
|
||||||
// When we enable this, we will need to add ACCESS_FINE_LOCATION
|
// if(!TextUtils.isEmpty(countryCode)) return countryCode;
|
||||||
//countryCode = getCountryFromLocation();
|
LOG.info("Falling back to SIM card country");
|
||||||
//if (!TextUtils.isEmpty(countryCode)) {
|
|
||||||
// return countryCode;
|
|
||||||
//}
|
|
||||||
countryCode = getCountryFromSimCard();
|
countryCode = getCountryFromSimCard();
|
||||||
if (!TextUtils.isEmpty(countryCode)) {
|
if(!TextUtils.isEmpty(countryCode)) return countryCode.toUpperCase();
|
||||||
LOG.info("Could not determine current country; fall back to SIM card country.");
|
LOG.info("Falling back to user-defined locale");
|
||||||
return countryCode.toUpperCase(); // android api gives lowercase for some reason
|
|
||||||
}
|
|
||||||
LOG.info("Could not determine current country; fall back to user-defined locale.");
|
|
||||||
return Locale.getDefault().getCountry();
|
return Locale.getDefault().getCountry();
|
||||||
}
|
}
|
||||||
|
|
||||||
String getCountryFromPhoneNetwork() {
|
private String getCountryFromPhoneNetwork() {
|
||||||
TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
|
Object o = ctx.getSystemService(TELEPHONY_SERVICE);
|
||||||
|
TelephonyManager tm = (TelephonyManager) o;
|
||||||
return tm.getNetworkCountryIso();
|
return tm.getNetworkCountryIso();
|
||||||
}
|
}
|
||||||
|
|
||||||
String getCountryFromSimCard() {
|
private String getCountryFromSimCard() {
|
||||||
TelephonyManager tm = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
|
Object o = ctx.getSystemService(TELEPHONY_SERVICE);
|
||||||
|
TelephonyManager tm = (TelephonyManager) o;
|
||||||
return tm.getSimCountryIso();
|
return tm.getSimCountryIso();
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this is not currently used, because it involves a network call
|
// TODO: this is not currently used, because it involves a network call
|
||||||
// it should be possible to determine country just from the long/lat, but
|
// it should be possible to determine country just from the long/lat, but
|
||||||
// this would involve something like tzdata for countries.
|
// this would involve something like tzdata for countries.
|
||||||
String getCountryFromLocation() {
|
private String getCountryFromLocation() {
|
||||||
Location location = getLastKnownLocation();
|
Location location = getLastKnownLocation();
|
||||||
if (location == null) return null;
|
if(location == null) return null;
|
||||||
Geocoder code = new Geocoder(context);
|
Geocoder code = new Geocoder(ctx);
|
||||||
try {
|
try {
|
||||||
List<Address> addresses = code.getFromLocation(location.getLatitude(), location.getLongitude(), 1);
|
double lat = location.getLatitude();
|
||||||
if (addresses.isEmpty()) return null;
|
double lon = location.getLongitude();
|
||||||
|
List<Address> addresses = code.getFromLocation(lat, lon, 1);
|
||||||
|
if(addresses.isEmpty()) return null;
|
||||||
return addresses.get(0).getCountryCode();
|
return addresses.get(0).getCountryCode();
|
||||||
} catch (IOException e) {
|
} catch(IOException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the last location from all location providers.
|
* Returns the last location from all location providers, or null if there
|
||||||
* Since we're only checking the country, we don't care about the accuracy.
|
* is no such location. Since we're only checking the country, we don't
|
||||||
* If we ever need the accuracy, we can do something like:
|
* care about the accuracy. If we ever need the accuracy, we can do
|
||||||
* https://code.google.com/p/android-protips-location/source/browse/trunk\
|
* something like <a href="https://code.google.com/p/android-protips-location/source/browse/trunk/src/com/radioactiveyak/location_best_practices/utils/GingerbreadLastLocationFinder.java">
|
||||||
* /src/com/radioactiveyak/location_best_practices/utils/GingerbreadLastLocationFinder.java
|
* this</a>.
|
||||||
*/
|
*/
|
||||||
Location getLastKnownLocation() {
|
private Location getLastKnownLocation() {
|
||||||
LocationManager locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
|
Object o = ctx.getSystemService(LOCATION_SERVICE);
|
||||||
|
LocationManager locationManager = (LocationManager) o;
|
||||||
Location bestResult = null;
|
Location bestResult = null;
|
||||||
long bestTime = Long.MIN_VALUE;
|
long bestTime = Long.MIN_VALUE;
|
||||||
for (String provider: locationManager.getAllProviders()) {
|
for(String provider : locationManager.getAllProviders()) {
|
||||||
Location location = locationManager.getLastKnownLocation(provider);
|
Location location = locationManager.getLastKnownLocation(provider);
|
||||||
if (location == null) continue;
|
if(location == null) continue;
|
||||||
long time = location.getTime();
|
long time = location.getTime();
|
||||||
if (time > bestTime) {
|
if(time > bestTime) {
|
||||||
bestResult = location;
|
bestResult = location;
|
||||||
bestTime = time;
|
bestTime = time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return bestResult;
|
return bestResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ package org.briarproject.api.system;
|
|||||||
|
|
||||||
public interface LocationUtils {
|
public interface LocationUtils {
|
||||||
|
|
||||||
/** Get the country the device is currently-located in, or "" if it cannot
|
/**
|
||||||
|
* Get the country the device is currently located in, or "" if it cannot
|
||||||
* be determined. Should never return {@code null}.
|
* be determined. Should never return {@code null}.
|
||||||
*
|
* <p>
|
||||||
* <p>The country codes are formatted upper-case and as per <a href="
|
* The country codes are formatted upper-case and as per <a href="
|
||||||
* https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">ISO 3166-1 alpha 2</a>.
|
* https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2">ISO 3166-1 alpha 2</a>.
|
||||||
*/
|
*/
|
||||||
String getCurrentCountry();
|
String getCurrentCountry();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user