summaryrefslogtreecommitdiff
path: root/main/src
diff options
context:
space:
mode:
Diffstat (limited to 'main/src')
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java67
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java2
-rw-r--r--main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java13
3 files changed, 66 insertions, 16 deletions
diff --git a/main/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java b/main/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java
index 9feedf63..240e9e32 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java
@@ -12,15 +12,19 @@ import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.NetworkInfo.State;
+import android.os.Handler;
import android.preference.PreferenceManager;
+
import de.blinkt.openvpn.R;
import de.blinkt.openvpn.core.VpnStatus.ByteCountListener;
import java.util.LinkedList;
+import java.util.Objects;
import static de.blinkt.openvpn.core.OpenVPNManagement.pauseReason;
public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountListener {
+ private final Handler mDisconnectHandler;
private int lastNetwork = -1;
private OpenVPNManagement mManagement;
@@ -29,12 +33,31 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL
// Data traffic limit in bytes
private final long TRAFFIC_LIMIT = 64 * 1024;
+ // Time to wait after network disconnect to pause the VPN
+ private final int DISCONNECT_WAIT = 20;
+
connectState network = connectState.DISCONNECTED;
connectState screen = connectState.SHOULDBECONNECTED;
connectState userpause = connectState.SHOULDBECONNECTED;
private String lastStateMsg = null;
+ private java.lang.Runnable mDelayDisconnectRunnable = new Runnable() {
+ @Override
+ public void run() {
+ if (!(network == connectState.PENDINGDISCONNECT))
+ return;
+
+ network = connectState.DISCONNECTED;
+
+ // Set screen state to be disconnected if disconnect pending
+ if (screen == connectState.PENDINGDISCONNECT)
+ screen = connectState.DISCONNECTED;
+
+ mManagement.pause(getPauseReason());
+ }
+ };
+ private NetworkInfo lastConnectedNetwork;
enum connectState {
SHOULDBECONNECTED,
@@ -54,6 +77,7 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL
LinkedList<Datapoint> trafficdata = new LinkedList<DeviceStateReceiver.Datapoint>();
+
@Override
public void updateByteCount(long in, long out, long diffIn, long diffOut) {
if (screen != connectState.PENDINGDISCONNECT)
@@ -99,6 +123,7 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL
public DeviceStateReceiver(OpenVPNManagement magnagement) {
super();
mManagement = magnagement;
+ mDisconnectHandler = new Handler();
}
@@ -113,7 +138,7 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL
boolean screenOffPause = prefs.getBoolean("screenoff", false);
if (screenOffPause) {
- if (ProfileManager.getLastConnectedVpn()!=null && !ProfileManager.getLastConnectedVpn().mPersistTun)
+ if (ProfileManager.getLastConnectedVpn() != null && !ProfileManager.getLastConnectedVpn().mPersistTun)
VpnStatus.logError(R.string.screen_nopersistenttun);
screen = connectState.PENDINGDISCONNECT;
@@ -126,6 +151,8 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL
boolean connected = shouldBeConnected();
screen = connectState.SHOULDBECONNECTED;
+ /* We should connect now, cancel any outstanding disconnect timer */
+ mDisconnectHandler.removeCallbacks(mDelayDisconnectRunnable);
/* should be connected has changed because the screen is on now, connect the VPN */
if (shouldBeConnected() != connected)
mManagement.resume();
@@ -140,6 +167,10 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL
private void fillTrafficData() {
trafficdata.add(new Datapoint(System.currentTimeMillis(), TRAFFIC_LIMIT));
}
+ public static boolean equalsObj(Object a, Object b) {
+ return (a == null) ? (b == null) : a.equals(b);
+ }
+
public void networkStateChange(Context context) {
@@ -175,34 +206,49 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL
if (networkInfo != null && networkInfo.getState() == State.CONNECTED) {
int newnet = networkInfo.getType();
+
+ boolean pendingDisconnect = (network == connectState.PENDINGDISCONNECT);
network = connectState.SHOULDBECONNECTED;
- if (lastNetwork != newnet) {
+ boolean sameNetwork;
+ if (lastConnectedNetwork == null
+ || lastConnectedNetwork.getType() != networkInfo.getType()
+ || !equalsObj(lastConnectedNetwork.getExtraInfo(), networkInfo.getExtraInfo())
+ )
+ sameNetwork = false;
+ else
+ sameNetwork = true;
+
+ if (pendingDisconnect && sameNetwork) {
+ mDisconnectHandler.removeCallbacks(mDelayDisconnectRunnable);
+ // Reprotect the sockets just be sure
+ mManagement.networkChange(true);
+ }
+
+ if (!sameNetwork) {
if (screen == connectState.PENDINGDISCONNECT)
screen = connectState.DISCONNECTED;
if (shouldBeConnected()) {
- if (lastNetwork == -1) {
+ mDisconnectHandler.removeCallbacks(mDelayDisconnectRunnable);
+ if (lastNetwork == -1 && !pendingDisconnect) {
mManagement.resume();
} else {
- mManagement.networkChange();
+ mManagement.networkChange(false);
}
}
lastNetwork = newnet;
+ lastConnectedNetwork = networkInfo;
}
} else if (networkInfo == null) {
// Not connected, stop openvpn, set last connected network to no network
lastNetwork = -1;
if (sendusr1) {
- network = connectState.DISCONNECTED;
+ network = connectState.PENDINGDISCONNECT;
+ mDisconnectHandler.postDelayed(mDelayDisconnectRunnable, DISCONNECT_WAIT * 1000);
- // Set screen state to be disconnected if disconnect pending
- if (screen == connectState.PENDINGDISCONNECT)
- screen = connectState.DISCONNECTED;
-
- mManagement.pause(getPauseReason());
}
}
@@ -213,6 +259,7 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL
}
+
public boolean isUserPaused() {
return userpause == connectState.DISCONNECTED;
}
diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java
index 1f28c77d..d7666933 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVPNManagement.java
@@ -25,5 +25,5 @@ public interface OpenVPNManagement {
/*
* Rebind the interface
*/
- void networkChange();
+ void networkChange(boolean sameNetwork);
}
diff --git a/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java b/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java
index da249cc4..e27feab0 100644
--- a/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java
+++ b/main/src/main/java/de/blinkt/openvpn/core/OpenVpnManagementThread.java
@@ -12,7 +12,7 @@ import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.os.ParcelFileDescriptor;
import android.preference.PreferenceManager;
-import android.support.annotation.NonNull;
+import android.support.annotation.NonNull;
import android.util.Log;
import junit.framework.Assert;
@@ -64,7 +64,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
}
- public boolean openManagementInterface(@NonNull Context c) {
+ public boolean openManagementInterface(@NonNull Context c) {
// Could take a while to open connection
int tries = 8;
@@ -248,7 +248,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
Log.i(TAG, "Got unrecognized command" + command);
}
} else if (command.startsWith("SUCCESS:")) {
- /* Ignore this kind of message too */
+ /* Ignore this kind of message too */
return;
} else if (command.startsWith("PROTECTFD: ")) {
FileDescriptor fdtoprotect = mFDList.pollFirst();
@@ -558,9 +558,12 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
}
@Override
- public void networkChange() {
+ public void networkChange(boolean samenetwork) {
if (!mWaitingForRelease)
- managmentCommand("network-change\n");
+ if (samenetwork)
+ managmentCommand("network-change samenetwork\n");
+ else
+ managmentCommand("network-change\n");
}
public void signalusr1() {