Made coding style consistent with rest of project.

This commit is contained in:
akwizgran
2014-03-06 13:16:20 +00:00
parent 7838c3687a
commit 0198e40719
4 changed files with 68 additions and 87 deletions

View File

@@ -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;
} }
} }

View File

@@ -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,

View File

@@ -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;
} }
} }

View File

@@ -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();
} }