From 5b95785060adace6b48a69d560051261233d954d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Parm=C3=A9nides=20GV?= Date: Sat, 6 Feb 2016 13:00:53 +0100 Subject: Update ics-openvpn --- .../blinkt/openvpn/core/DeviceStateReceiver.java | 83 ++++++++++++++++++---- 1 file changed, 68 insertions(+), 15 deletions(-) (limited to 'app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java') diff --git a/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java b/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java index 4ccf5472..40684af3 100644 --- a/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java +++ b/app/src/main/java/de/blinkt/openvpn/core/DeviceStateReceiver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2014 Arne Schwabe + * Copyright (c) 2012-2016 Arne Schwabe * Distributed under the GNU GPL v2 with additional terms. For full terms see the file doc/LICENSE.txt */ @@ -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 se.leap.bitmaskclient.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 { +public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountListener, OpenVPNManagement.PausedStateCallback { + private final Handler mDisconnectHandler; private int lastNetwork = -1; private OpenVPNManagement mManagement; @@ -29,12 +33,36 @@ 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; + + @Override + public boolean shouldBeRunning() { + return shouldBeConnected(); + } enum connectState { SHOULDBECONNECTED, @@ -54,6 +82,7 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL LinkedList trafficdata = new LinkedList(); + @Override public void updateByteCount(long in, long out, long diffIn, long diffOut) { if (screen != connectState.PENDINGDISCONNECT) @@ -99,6 +128,8 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL public DeviceStateReceiver(OpenVPNManagement magnagement) { super(); mManagement = magnagement; + mManagement.setPauseCallback(this); + mDisconnectHandler = new Handler(); } @@ -113,7 +144,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 +157,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 +173,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 +212,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; + + /* Same network, connection still 'established' */ + if (pendingDisconnect && sameNetwork) { + mDisconnectHandler.removeCallbacks(mDelayDisconnectRunnable); + // Reprotect the sockets just be sure + mManagement.networkChange(true); + } else { + /* Different network or connection not established anymore */ + if (screen == connectState.PENDINGDISCONNECT) screen = connectState.DISCONNECTED; if (shouldBeConnected()) { - if (lastNetwork == -1) { - mManagement.resume(); - } else { - mManagement.networkChange(); + mDisconnectHandler.removeCallbacks(mDelayDisconnectRunnable); - } + if (pendingDisconnect || !sameNetwork) + mManagement.networkChange(sameNetwork); + else + mManagement.resume(); } 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; - - // Set screen state to be disconnected if disconnect pending - if (screen == connectState.PENDINGDISCONNECT) - screen = connectState.DISCONNECTED; + network = connectState.PENDINGDISCONNECT; + mDisconnectHandler.postDelayed(mDelayDisconnectRunnable, DISCONNECT_WAIT * 1000); - mManagement.pause(getPauseReason()); } } @@ -213,6 +265,7 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL } + public boolean isUserPaused() { return userpause == connectState.DISCONNECTED; } -- cgit v1.2.3