diff --git a/res/layout/layout_main.xml b/res/layout/layout_main.xml
index 104e96e4..a3b99dec 100644
--- a/res/layout/layout_main.xml
+++ b/res/layout/layout_main.xml
@@ -205,6 +205,12 @@ android:layout_gravity="center_horizontal|center_vertical"/>
android:ellipsize="end"
android:singleLine="true"
/>
+
+
diff --git a/src/org/torproject/android/OrbotMainActivity.java b/src/org/torproject/android/OrbotMainActivity.java
index f56069ea..a2e5a60f 100644
--- a/src/org/torproject/android/OrbotMainActivity.java
+++ b/src/org/torproject/android/OrbotMainActivity.java
@@ -44,7 +44,11 @@ import android.view.View.OnLongClickListener;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.view.animation.AccelerateInterpolator;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
import android.widget.Button;
+import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
@@ -66,6 +70,8 @@ import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.Collections;
import java.util.Locale;
@@ -83,6 +89,9 @@ public class OrbotMainActivity extends Activity
private Button mBtnBrowser = null;
private ToggleButton mBtnVPN = null;
private ToggleButton mBtnBridges = null;
+
+ private Spinner spnCountries = null;
+
private DrawerLayout mDrawer;
private ActionBarDrawerToggle mDrawerToggle;
@@ -297,8 +306,46 @@ public class OrbotMainActivity extends Activity
});
+ Locale[] locale = Locale.getAvailableLocales();
+ ArrayList countries = new ArrayList();
+ countries.add("World (best)");
+ countries.add("US");
+ countries.add("DE");
+ countries.add("CA");
+ countries.add("FR");
+
+
+ spnCountries = (Spinner)findViewById(R.id.spinnerCountry);
+ ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_spinner_item, countries);
+ spnCountries.setAdapter(adapter);
+
+ spnCountries.setOnItemSelectedListener(new OnItemSelectedListener() {
+ @Override
+ public void onItemSelected(AdapterView> parentView, View selectedItemView, int position, long id) {
+ // your code here
+
+ String country = (String)spnCountries.getItemAtPosition(position);
+
+ if (position == 0)
+ country = "";
+ else
+ country = '{' + country.toLowerCase() + '}';
+
+ Intent torService = new Intent(OrbotMainActivity.this, TorService.class);
+ torService.setAction(TorServiceConstants.CMD_SET_EXIT);
+ torService.putExtra("exit",country);
+ startService(torService);
+
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parentView) {
+ // your code here
+ }
+
+ });
}
GestureDetector mGestureDetector;
diff --git a/src/org/torproject/android/service/TorService.java b/src/org/torproject/android/service/TorService.java
index 5513e780..24f59656 100644
--- a/src/org/torproject/android/service/TorService.java
+++ b/src/org/torproject/android/service/TorService.java
@@ -339,6 +339,10 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
enableVpnProxy();
} else if (action.equals(CMD_VPN_CLEAR)) {
clearVpnProxy();
+ } else if (action.equals(CMD_SET_EXIT)) {
+
+ setExitNode(mIntent.getStringExtra("exit"));
+
} else {
Log.w(TAG, "unhandled TorService Intent: " + action);
}
@@ -2088,38 +2092,25 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
if (entranceNodes.length() > 0 || exitNodes.length() > 0 || excludeNodes.length() > 0)
{
- //only apply GeoIP if you need it
- File fileGeoIP = new File(OrbotApp.appBinHome, GEOIP_ASSET_KEY);
- File fileGeoIP6 = new File(OrbotApp.appBinHome, GEOIP6_ASSET_KEY);
-
- try
- {
- if ((!fileGeoIP.exists()))
- {
- TorResourceInstaller installer = new TorResourceInstaller(this, OrbotApp.appBinHome);
- boolean success = installer.installGeoIP();
+
+ if (enableGeoIP ())
+ { //only apply GeoIP if you need it
+ File fileGeoIP = new File(OrbotApp.appBinHome, GEOIP_ASSET_KEY);
+ File fileGeoIP6 = new File(OrbotApp.appBinHome, GEOIP6_ASSET_KEY);
- }
-
extraLines.append("GeoIPFile" + ' ' + fileGeoIP.getCanonicalPath()).append('\n');
extraLines.append("GeoIPv6File" + ' ' + fileGeoIP6.getCanonicalPath()).append('\n');
-
- }
- catch (Exception e)
- {
- showToolbarNotification (getString(R.string.error_installing_binares),ERROR_NOTIFY_ID,R.drawable.ic_stat_notifyerr);
-
- return false;
}
+
}
- if (entranceNodes != null && entranceNodes.length() > 0)
+ if (!TextUtils.isEmpty(entranceNodes))
extraLines.append("EntryNodes" + ' ' + entranceNodes).append('\n');
- if (exitNodes != null && exitNodes.length() > 0)
+ if (!TextUtils.isEmpty(exitNodes))
extraLines.append("ExitNodes" + ' ' + exitNodes).append('\n');
- if (excludeNodes != null && excludeNodes.length() > 0)
+ if (!TextUtils.isEmpty(excludeNodes))
extraLines.append("ExcludeNodes" + ' ' + excludeNodes).append('\n');
extraLines.append("StrictNodes" + ' ' + (enableStrictNodes ? "1" : "0")).append('\n');
@@ -2210,14 +2201,6 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
}
- if (Prefs.useVpn())
- {
-
- //extraLines.append("DNSPort ").append(TOR_VPN_DNS_LISTEN_ADDRESS).append(":").append(TorServiceConstants.TOR_DNS_PORT_DEFAULT).append("\n");
- //extraLines.append("DNSPort ").append(TorServiceConstants.TOR_DNS_PORT_DEFAULT).append("\n");
-
- }
-
return true;
}
@@ -2337,6 +2320,93 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
return null;
}
+ private void setExitNode (String newExits)
+ {
+ SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext());
+
+ if (TextUtils.isEmpty(newExits))
+ {
+ prefs.edit().remove("pref_exit_nodes").apply();
+
+ if (conn != null)
+ {
+ try
+ {
+ ArrayList resetBuffer = new ArrayList();
+ resetBuffer.add("ExitNodes");
+ resetBuffer.add("StrictNodes");
+ conn.resetConf(resetBuffer);
+ conn.setConf("DisableNetwork","1");
+ conn.setConf("DisableNetwork","0");
+
+ }
+ catch (IOException ioe)
+ {
+ ioe.printStackTrace();
+ }
+ }
+ }
+ else
+ {
+ prefs.edit().putString("pref_exit_nodes", newExits).apply();
+
+ if (conn != null)
+ {
+ try
+ {
+
+ enableGeoIP ();
+
+ File fileGeoIP = new File(OrbotApp.appBinHome, GEOIP_ASSET_KEY);
+ File fileGeoIP6 = new File(OrbotApp.appBinHome, GEOIP6_ASSET_KEY);
+
+ conn.setConf("GeoIPFile",fileGeoIP.getCanonicalPath());
+ conn.setConf("GeoIPv6File",fileGeoIP6.getCanonicalPath());
+
+ conn.setConf("ExitNodes", newExits);
+ conn.setConf("StrictNodes","1");
+
+ conn.setConf("DisableNetwork","1");
+ conn.setConf("DisableNetwork","0");
+
+
+
+
+ }
+ catch (IOException ioe)
+ {
+ ioe.printStackTrace();
+ }
+ }
+ }
+
+
+
+ }
+ private boolean enableGeoIP ()
+ {
+ File fileGeoIP = new File(OrbotApp.appBinHome, GEOIP_ASSET_KEY);
+ File fileGeoIP6 = new File(OrbotApp.appBinHome, GEOIP6_ASSET_KEY);
+
+ try
+ {
+ if ((!fileGeoIP.exists()))
+ {
+ TorResourceInstaller installer = new TorResourceInstaller(this, OrbotApp.appBinHome);
+ boolean success = installer.installGeoIP();
+
+ }
+
+ return true;
+
+ }
+ catch (Exception e)
+ {
+ showToolbarNotification (getString(R.string.error_installing_binares),ERROR_NOTIFY_ID,R.drawable.ic_stat_notifyerr);
+
+ return false;
+ }
+ }
}
diff --git a/src/org/torproject/android/service/TorServiceConstants.java b/src/org/torproject/android/service/TorServiceConstants.java
index 77b7a9bf..c9bb6ecd 100644
--- a/src/org/torproject/android/service/TorServiceConstants.java
+++ b/src/org/torproject/android/service/TorServiceConstants.java
@@ -131,7 +131,10 @@ public interface TorServiceConstants {
public static final String CMD_VPN = "vpn";
public static final String CMD_VPN_CLEAR = "vpnclear";
public static final String CMD_UPDATE_TRANS_PROXY = "update";
-
+ public static final String CMD_SET_EXIT = "setexit";
+
+
+
public static final String BINARY_TOR_VERSION = "0.2.7.5-020120160125";
public static final String PREF_BINARY_TOR_VERSION_INSTALLED = "BINARY_TOR_VERSION_INSTALLED";