[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [orbot/master] Improve VPN service support - fix network switching handling
commit 75426bb9e25d11fa84636481aac59094eec41b26
Author: Nathan Freitas <nathan@xxxxxxxxxxx>
Date: Fri Apr 3 12:27:59 2015 -0400
Improve VPN service support - fix network switching handling
We now refresh the VPN and tun2socks interfaces when the network
type switches, and we do so in a way that does not cause traffic to leak.
The new interface is established before we close the old one.
---
res/values/arrays.xml | 13 +-
res/values/strings.xml | 13 +-
src/org/torproject/android/OrbotConstants.java | 2 +-
src/org/torproject/android/OrbotMainActivity.java | 180 ++++++++++++++++----
src/org/torproject/android/service/TorService.java | 134 +++++++++++----
.../torproject/android/vpn/OrbotVpnService.java | 157 ++++++++++-------
6 files changed, 359 insertions(+), 140 deletions(-)
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
index fb0a7c3..00eb3a4 100644
--- a/res/values/arrays.xml
+++ b/res/values/arrays.xml
@@ -36,9 +36,16 @@
<item>ru</item>
-
-
-
+ </string-array>
+
+ <string-array name="bridge_options">
+ <item>Obfs4 (Recommended)</item>
+ <item>Obfs3</item>
+ <item>ScrambleSuit</item>
+ <item>Tunnel through Azure</item>
+ <item>Tunnel through Amazon</item>
+ <item>Tunnel through Google</item>
+ <item></item>
</string-array>
</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 92e1e35..e76ce28 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -315,15 +315,16 @@
<string name="bridges_updated">Bridges Updated</string>
- <string name="restart_orbot_to_use_this_bridge_">"Restart Orbot to use these bridges: "</string>
+ <string name="restart_orbot_to_use_this_bridge_">Please restart Orbot to enable the changes</string>
<string name="menu_qr">QR Codes</string>
- <string name="if_your_mobile_network_actively_blocks_tor_you_can_use_a_tor_bridge_to_access_the_network_another_way_to_get_bridges_is_to_send_an_email_to_bridges_torproject_org_please_note_that_you_must_send_the_email_using_an_address_from_one_of_the_following_email_providers_riseup_gmail_or_yahoo_">If your mobile network actively blocks Tor, you can use a Tor Bridge to access the network.\n\nYou can get a bridge address from https://bridges.torproject.org or scan a bridge QR code from a friend.\n\nAnother way to get bridges is to send an email to bridges@xxxxxxxxxxxxxxx Please note that you must send the email using an address from one of the following email providers: Riseup, Gmail or Yahoo.</string>
+ <string name="if_your_mobile_network_actively_blocks_tor_you_can_use_a_tor_bridge_to_access_the_network_another_way_to_get_bridges_is_to_send_an_email_to_bridges_torproject_org_please_note_that_you_must_send_the_email_using_an_address_from_one_of_the_following_email_providers_riseup_gmail_or_yahoo_">If your mobile network actively blocks Tor, you can use a Tor Bridge to access the network.\n\nYou can get a bridge address from https://bridges.torproject.org, by emailing bridges@xxxxxxxxxxxxxx, or by scanning a bridge QR code.</string>
<string name="bridge_mode">Bridge Mode</string>
- <string name="get_bridges">Get Bridges</string>
+ <string name="get_bridges_email">Email</string>
+ <string name="get_bridges_web">Web</string>
<string name="activate">Activate</string>
@@ -332,4 +333,10 @@
<string name="you_can_enable_all_apps_on_your_device_to_run_through_the_tor_network_using_the_vpn_feature_of_android_">You can enable all apps on your device to run through the Tor network using the VPN feature of Android.\n\n*WARNING* This is a new, experimental feature and in some cases may not start automatically, or may stop. It should NOT be used for anonymity, and ONLY used for getting through firewalls and filters.</string>
<string name="send_email">Send Email</string>
+
+ <string name="you_must_get_a_bridge_address_by_email_web_or_from_a_friend_once_you_have_this_address_please_paste_it_into_the_bridges_preference_in_orbot_s_setting_and_restart_">You must can a bridge address by email, web or by scanning a bridge QR code. Once you have this address, please paste it into the \"Bridges\" preference in Orbot\'s setting and restart.</string>
+
+ <string name="install_orweb">Install Orweb</string>
+
+ <string name="standard_browser">Standard Browser</string>
</resources>
diff --git a/src/org/torproject/android/OrbotConstants.java b/src/org/torproject/android/OrbotConstants.java
index 745ace4..fa67d92 100644
--- a/src/org/torproject/android/OrbotConstants.java
+++ b/src/org/torproject/android/OrbotConstants.java
@@ -16,7 +16,7 @@ public interface OrbotConstants {
//path to check Tor against
public final static String URL_TOR_CHECK = "https://check.torproject.org";
- public final static String URL_TOR_BRIDGES = "https://bridges.torproject.org";
+ public final static String URL_TOR_BRIDGES = "https://bridges.torproject.org/bridges?transport=";
public final static String NEWLINE = "\n";
diff --git a/src/org/torproject/android/OrbotMainActivity.java b/src/org/torproject/android/OrbotMainActivity.java
index be05d69..2e22fb2 100644
--- a/src/org/torproject/android/OrbotMainActivity.java
+++ b/src/org/torproject/android/OrbotMainActivity.java
@@ -661,6 +661,8 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
setResult(RESULT_OK);
mBtnBridges.setChecked(true);
+
+ enableBridges(true);
}
private boolean showWizard = true;
@@ -707,7 +709,7 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
.setIcon(R.drawable.onion32)
.setTitle(R.string.install_apps_)
.setMessage(R.string.it_doesn_t_seem_like_you_have_orweb_installed_want_help_with_that_or_should_we_just_open_the_browser_)
- .setPositiveButton(android.R.string.ok, new Dialog.OnClickListener ()
+ .setPositiveButton(R.string.install_orweb, new Dialog.OnClickListener ()
{
@Override
@@ -720,7 +722,7 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
}
})
- .setNegativeButton(android.R.string.no, new Dialog.OnClickListener ()
+ .setNegativeButton(R.string.standard_browser, new Dialog.OnClickListener ()
{
@Override
@@ -860,41 +862,56 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
new AlertDialog.Builder(this)
.setTitle(R.string.bridge_mode)
.setView(view)
- .setNeutralButton(R.string.get_bridges, new Dialog.OnClickListener ()
- {
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
-
- //openBrowser(URL_TOR_BRIDGES);
-
- sendGetBridgeEmail();
- }
-
-
- })
- .setPositiveButton(R.string.activate, new Dialog.OnClickListener ()
- {
-
- @Override
- public void onClick(DialogInterface dialog, int which) {
-
- enableBridges (true);
-
- }
-
-
- })
- .setNegativeButton(android.R.string.cancel, new Dialog.OnClickListener()
+ .setItems(R.array.bridge_options, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ // The 'which' argument contains the index position
+ // of the selected item
+
+ switch (which)
+ {
+ case 0: //obfs 4;
+ showGetBridgePrompt("obfs4");
+
+ break;
+ case 1: //obfs3
+ showGetBridgePrompt("obfs3");
+
+ break;
+ case 2: //scramblesuit
+ showGetBridgePrompt("scramblesuit");
+
+ break;
+ case 3: //azure
+ mPrefs.edit().putString(OrbotConstants.PREF_BRIDGES_LIST,"2").commit();
+ enableBridges(true);
+
+ break;
+ case 4: //amazon
+ mPrefs.edit().putString(OrbotConstants.PREF_BRIDGES_LIST,"1").commit();
+ enableBridges(true);
+
+ break;
+ case 5: //google
+ mPrefs.edit().putString(OrbotConstants.PREF_BRIDGES_LIST,"0").commit();
+ enableBridges(true);
+
+ break;
+
+ }
+
+ }
+ }).setNegativeButton(android.R.string.cancel, new Dialog.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which) {
- mBtnBridges.setChecked(false);
+ //mBtnBridges.setChecked(false);
}
})
.show();
+
+
}
else
{
@@ -903,13 +920,72 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
}
- private void sendGetBridgeEmail ()
+ private void showGetBridgePrompt (final String type)
+ {
+ LayoutInflater li = LayoutInflater.from(this);
+ View view = li.inflate(R.layout.layout_diag, null);
+
+ TextView versionName = (TextView)view.findViewById(R.id.diaglog);
+ versionName.setText(R.string.you_must_get_a_bridge_address_by_email_web_or_from_a_friend_once_you_have_this_address_please_paste_it_into_the_bridges_preference_in_orbot_s_setting_and_restart_);
+
+ new AlertDialog.Builder(this)
+ .setTitle(R.string.bridge_mode)
+ .setView(view)
+ .setNegativeButton(android.R.string.cancel, new Dialog.OnClickListener()
+ {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+
+ //mBtnBridges.setChecked(false);
+
+ }
+ })
+ .setNeutralButton(R.string.get_bridges_email, new Dialog.OnClickListener ()
+ {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+
+
+ sendGetBridgeEmail(type);
+
+ }
+
+
+ })
+ .setPositiveButton(R.string.get_bridges_web, new Dialog.OnClickListener ()
+ {
+
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+
+ openBrowser(URL_TOR_BRIDGES + type);
+
+ }
+
+
+ }).show();
+ }
+
+ private void sendGetBridgeEmail (String type)
{
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("message/rfc822");
intent.putExtra(Intent.EXTRA_EMAIL , new String[]{"bridges@xxxxxxxxxxxxxx"});
- intent.putExtra(Intent.EXTRA_SUBJECT, "Tor Bridge Request");
-
+
+ if (type != null)
+ {
+ intent.putExtra(Intent.EXTRA_SUBJECT, "get transport " + type);
+ intent.putExtra(Intent.EXTRA_TEXT, "get transport " + type);
+
+ }
+ else
+ {
+ intent.putExtra(Intent.EXTRA_SUBJECT, "get bridges");
+ intent.putExtra(Intent.EXTRA_TEXT, "get bridges");
+
+ }
+
startActivity(Intent.createChooser(intent, getString(R.string.send_email)));
}
@@ -917,10 +993,45 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
{
Editor edit = mPrefs.edit();
- edit.putBoolean("pref_bridges_enabled", enable);
+ edit.putBoolean(OrbotConstants.PREF_BRIDGES_ENABLED, enable);
edit.commit();
updateSettings();
+
+ if (torStatus == TorServiceConstants.STATUS_ON)
+ {
+ String bridgeList = mPrefs.getString(OrbotConstants.PREF_BRIDGES_LIST,null);
+ if (bridgeList != null && bridgeList.length() > 0)
+ {
+ try
+ {
+ //do auto restart
+ stopTor ();
+
+ mHandler.postDelayed(new Runnable () {
+
+ public void run ()
+ {
+ try
+ {
+ startTor();
+ }
+ catch (Exception e)
+ {
+ Log.e(TAG,"can't start orbot",e);
+ }
+ }
+ }, 2000);
+ }
+ catch (Exception e)
+ {
+ Log.e(TAG,"can't stop orbot",e);
+ }
+ }
+
+ }
+
+
}
public void promptStartVpnService ()
@@ -1160,7 +1271,7 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
//here we update the UI which is a bit sloppy and mixed up code wise
//might be best to just call updateStatus() instead of directly manipulating UI in this method - yep makes sense
imgStatus.setImageResource(R.drawable.torstarting);
- // lblStatus.setText(getString(R.string.status_starting_up));
+ lblStatus.setText(getString(R.string.status_starting_up));
//we send a message here to the progressDialog i believe, but we can clarify that shortly
Message msg = mHandler.obtainMessage(TorServiceConstants.ENABLE_TOR_MSG);
@@ -1168,7 +1279,6 @@ public class OrbotMainActivity extends Activity implements OrbotConstants, OnLon
mHandler.sendMessage(msg);
-
}
//now we stop Tor! amazing!
diff --git a/src/org/torproject/android/service/TorService.java b/src/org/torproject/android/service/TorService.java
index 9529d6d..cae1697 100644
--- a/src/org/torproject/android/service/TorService.java
+++ b/src/org/torproject/android/service/TorService.java
@@ -96,7 +96,7 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
private int mPortHTTP = 8118;
private int mPortSOCKS = 9050;
- private int mVpnProxyPort = 7231;
+ private int mVpnProxyPort = 9099;
private static final int NOTIFY_ID = 1;
private static final int TRANSPROXY_NOTIFY_ID = 2;
@@ -1475,6 +1475,18 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
}
+ public void refreshVpnProxy () {
+
+ debug ("refreshing VPN Proxy");
+
+ Intent intent = new Intent(TorService.this, OrbotVpnService.class);
+ intent.setAction("refresh");
+ startService(intent);
+
+ }
+
+
+
public void clearVpnProxy ()
{
debug ("clearing VPN Proxy");
@@ -1911,6 +1923,31 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
return false;
}
+ public void setTorNetworkEnabled (final boolean isEnabled)
+ {
+
+
+ //it is possible to not have a connection yet, and someone might try to newnym
+ if (conn != null)
+ {
+ new Thread ()
+ {
+ public void run ()
+ {
+ try {
+
+ conn.setConf("DisableNetwork", isEnabled ? "0" : "1");
+
+ }
+ catch (Exception ioe){
+ debug("error requesting newnym: " + ioe.getLocalizedMessage());
+ }
+ }
+ }.start();
+ }
+
+ }
+
public void newIdentity ()
{
//it is possible to not have a connection yet, and someone might try to newnym
@@ -2048,52 +2085,75 @@ public class TorService extends Service implements TorServiceConstants, OrbotCon
final ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkInfo netInfo = cm.getActiveNetworkInfo();
+ boolean newConnectivityState = false;
+
if(netInfo != null && netInfo.isConnected()) {
// WE ARE CONNECTED: DO SOMETHING
- mConnectivity = true;
+ newConnectivityState = true;
}
else {
// WE ARE NOT: DO SOMETHING ELSE
- mConnectivity = false;
+ newConnectivityState = false;
}
- if (doNetworKSleep)
+ //is this a change in state?
+ if (mConnectivity != newConnectivityState)
{
- try {
- updateConfiguration("DisableNetwork", mConnectivity ? "0" : "1", false);
-
- if (mCurrentStatus != STATUS_OFF)
- {
- if (!mConnectivity)
- {
- logNotice(context.getString(R.string.no_network_connectivity_putting_tor_to_sleep_));
- showToolbarNotification(getString(R.string.no_internet_connection_tor),NOTIFY_ID,R.drawable.ic_stat_tor_off);
-
- }
- else
- {
- logNotice(context.getString(R.string.network_connectivity_is_good_waking_tor_up_));
- showToolbarNotification(getString(R.string.status_activated),NOTIFY_ID,R.drawable.ic_stat_tor);
-
- if (mHasRoot && mEnableTransparentProxy && mTransProxyNetworkRefresh)
- {
-
- Shell shell = Shell.startRootShell();
-
- disableTransparentProxy(shell);
- enableTransparentProxy(shell);
-
- shell.close();
- }
-
- }
- }
-
- } catch (Exception e) {
- logException ("error updating state after network restart",e);
- }
+
+ if (doNetworKSleep)
+ {
+ try {
+
+ setTorNetworkEnabled (mConnectivity);
+
+ if (mCurrentStatus != STATUS_OFF)
+ {
+ if (!mConnectivity)
+ {
+ logNotice(context.getString(R.string.no_network_connectivity_putting_tor_to_sleep_));
+ showToolbarNotification(getString(R.string.no_internet_connection_tor),NOTIFY_ID,R.drawable.ic_stat_tor_off);
+
+ }
+ else
+ {
+ logNotice(context.getString(R.string.network_connectivity_is_good_waking_tor_up_));
+ showToolbarNotification(getString(R.string.status_activated),NOTIFY_ID,R.drawable.ic_stat_tor);
+
+ if (mHasRoot && mEnableTransparentProxy && mTransProxyNetworkRefresh)
+ {
+
+ Shell shell = Shell.startRootShell();
+
+ disableTransparentProxy(shell);
+ enableTransparentProxy(shell);
+
+ shell.close();
+ }
+
+ }
+ }
+
+ saveConfiguration();
+
+ } catch (Exception e) {
+ logException ("error updating state after network restart",e);
+ }
+ }
+
+ if (mUseVPN && mConnectivity && (mCurrentStatus != STATUS_OFF)) //we need to turn on VPN here so the proxy is running
+ {
+ setTorNetworkEnabled (false);
+ refreshVpnProxy();
+ setTorNetworkEnabled (true);
+
+
+ }
}
+ mConnectivity = newConnectivityState;
+
+
+
}
};
diff --git a/src/org/torproject/android/vpn/OrbotVpnService.java b/src/org/torproject/android/vpn/OrbotVpnService.java
index 2127562..b495937 100644
--- a/src/org/torproject/android/vpn/OrbotVpnService.java
+++ b/src/org/torproject/android/vpn/OrbotVpnService.java
@@ -57,6 +57,10 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
private final static int VPN_MTU = 1500;
+ private final static boolean isLollipop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
+
+ private boolean isRestart = false;
+
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
@@ -76,7 +80,7 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
// Stop the previous session by interrupting the thread.
if (mThreadVPN == null || (!mThreadVPN.isAlive()))
{
- boolean isLollipop = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
+
if (!isLollipop)
startSocksBypass();
@@ -89,6 +93,13 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
if (mHandler != null)
mHandler.postDelayed(new Runnable () { public void run () { stopSelf(); }}, 1000);
}
+ else if (action.equals("refresh"))
+ {
+ if (!isLollipop)
+ startSocksBypass();
+
+ setupTun2Socks();
+ }
return START_NOT_STICKY;
@@ -102,6 +113,12 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
{
try {
+
+ if (mSocksProxyServer != null)
+ {
+ stopSocksBypass ();
+ }
+
mSocksProxyServer = new ProxyServer(new ServerAuthenticatorNone(null, null));
ProxyServer.setVpnService(OrbotVpnService.this);
mSocksProxyServer.start(mSocksProxyPort, 5, InetAddress.getLocalHost());
@@ -115,10 +132,20 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
}
+ private void stopSocksBypass ()
+ {
+
+ if (mSocksProxyServer != null){
+ mSocksProxyServer.stop();
+ mSocksProxyServer = null;
+ }
+
+
+ }
+
@Override
public void onDestroy() {
stopVPN();
-
}
private void stopVPN ()
@@ -126,10 +153,7 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
Tun2Socks.Stop();
- if (mSocksProxyServer != null){
- mSocksProxyServer.stop();
- mSocksProxyServer = null;
- }
+ stopSocksBypass ();
if (mInterface != null){
try
@@ -167,54 +191,64 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
public void run ()
{
- if (mInterface == null)
- {
- try
+ try
+ {
+
+ // Set the locale to English (or probably any other language that^M
+ // uses Hindu-Arabic (aka Latin) numerals).^M
+ // We have found that VpnService.Builder does something locale-dependent^M
+ // internally that causes errors when the locale uses its own numerals^M
+ // (i.e., Farsi and Arabic).^M
+ Locale.setDefault(new Locale("en"));
+
+ //String localhost = InetAddress.getLocalHost().getHostAddress();
+
+ String vpnName = "OrbotVPN";
+ String virtualGateway = "10.0.0.1";
+ String virtualIP = "10.0.0.2";
+ String virtualNetMask = "255.255.255.0";
+ String localSocks = "127.0.0.1" + ':' + TorServiceConstants.PORT_SOCKS_DEFAULT;
+ String localDNS = "10.0.0.1" + ':' + TorServiceConstants.TOR_DNS_PORT_DEFAULT;
+
+
+ Builder builder = new Builder();
+
+ builder.setMtu(VPN_MTU);
+ builder.addAddress(virtualGateway,28);
+ builder.setSession(vpnName);
+ builder.addRoute("0.0.0.0",0);
+ // builder.addDnsServer("8.8.8.8");
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
-
- // Set the locale to English (or probably any other language that^M
- // uses Hindu-Arabic (aka Latin) numerals).^M
- // We have found that VpnService.Builder does something locale-dependent^M
- // internally that causes errors when the locale uses its own numerals^M
- // (i.e., Farsi and Arabic).^M
- Locale.setDefault(new Locale("en"));
-
- //String localhost = InetAddress.getLocalHost().getHostAddress();
-
- String vpnName = "OrbotVPN";
- String virtualGateway = "10.0.0.1";
- String virtualIP = "10.0.0.2";
- String virtualNetMask = "255.255.255.0";
- String localSocks = "127.0.0.1" + ':' + TorServiceConstants.PORT_SOCKS_DEFAULT;
- String localDNS = "10.0.0.1" + ':' + TorServiceConstants.TOR_DNS_PORT_DEFAULT;
-
-
- Builder builder = new Builder();
-
- builder.setMtu(VPN_MTU);
- builder.addAddress(virtualGateway,28);
- builder.setSession(vpnName);
- builder.addRoute("0.0.0.0",0);
- // builder.addDnsServer("8.8.8.8");
-
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
- {
- doLollipopAppRouting(builder);
- }
-
- // Create a new interface using the builder and save the parameters.
- mInterface = builder.setSession(mSessionName)
- .setConfigureIntent(mConfigureIntent)
- .establish();
-
- Tun2Socks.Start(mInterface, VPN_MTU, virtualIP, virtualNetMask, localSocks , localDNS , true);
+ doLollipopAppRouting(builder);
}
- catch (Exception e)
+
+ // Create a new interface using the builder and save the parameters.
+ ParcelFileDescriptor newInterface = builder.setSession(mSessionName)
+ .setConfigureIntent(mConfigureIntent)
+ .establish();
+
+ if (mInterface != null)
{
- Log.d(TAG,"tun2Socks has stopped",e);
+ isRestart = true;
+
+ Tun2Socks.Stop();
+ mInterface.close();
+
}
- }
- }
+
+
+ mInterface = newInterface;
+
+ Tun2Socks.Start(mInterface, VPN_MTU, virtualIP, virtualNetMask, localSocks , localDNS , true);
+ }
+ catch (Exception e)
+ {
+ Log.d(TAG,"tun2Socks has stopped",e);
+ }
+ }
+
};
mThreadVPN.start();
@@ -222,22 +256,23 @@ public class OrbotVpnService extends VpnService implements Handler.Callback {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void doLollipopAppRouting (Builder builder) throws NameNotFoundException
- {
-
-
- builder.addDisallowedApplication("org.torproject.android");
-
-
+ {
+ builder.addDisallowedApplication("org.torproject.android");
}
@Override
public void onRevoke() {
- SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext());
- prefs.edit().putBoolean("pref_vpn", false).commit();
-
- stopVPN();
-
+ if (!isRestart)
+ {
+ SharedPreferences prefs = TorServiceUtils.getSharedPrefs(getApplicationContext());
+ prefs.edit().putBoolean("pref_vpn", false).commit();
+ stopVPN();
+
+ }
+
+ isRestart = false;
+
super.onRevoke();
}
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits