diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/de/blinkt/openvpn/LogWindow.java | 88 | ||||
-rw-r--r-- | src/de/blinkt/openvpn/core/DeviceStateReceiver.java | 143 | ||||
-rw-r--r-- | src/de/blinkt/openvpn/core/OpenVPN.java | 43 | ||||
-rw-r--r-- | src/de/blinkt/openvpn/core/OpenVPNManagement.java | 10 | ||||
-rw-r--r-- | src/de/blinkt/openvpn/core/OpenVpnManagementThread.java | 83 | ||||
-rw-r--r-- | src/de/blinkt/openvpn/core/OpenVpnService.java | 73 |
6 files changed, 278 insertions, 162 deletions
diff --git a/src/de/blinkt/openvpn/LogWindow.java b/src/de/blinkt/openvpn/LogWindow.java index 5c78f2f6..1d75c154 100644 --- a/src/de/blinkt/openvpn/LogWindow.java +++ b/src/de/blinkt/openvpn/LogWindow.java @@ -1,21 +1,8 @@ package de.blinkt.openvpn; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Locale; -import java.util.Vector; - import android.app.AlertDialog; -import android.app.AlertDialog.Builder; import android.app.ListActivity; -import android.content.ClipData; -import android.content.ClipboardManager; -import android.content.ComponentName; -import android.content.Context; -import android.content.DialogInterface; -import android.content.DialogInterface.OnClickListener; -import android.content.Intent; -import android.content.ServiceConnection; +import android.content.*; import android.database.DataSetObserver; import android.os.Bundle; import android.os.Handler; @@ -23,17 +10,9 @@ import android.os.Handler.Callback; import android.os.IBinder; import android.os.Message; import android.text.format.DateFormat; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; +import android.view.*; +import android.widget.*; import android.widget.AdapterView.OnItemLongClickListener; -import android.widget.ListAdapter; -import android.widget.ListView; -import android.widget.TextView; -import android.widget.Toast; import de.blinkt.openvpn.core.OpenVPN; import de.blinkt.openvpn.core.OpenVPN.ConnectionStatus; import de.blinkt.openvpn.core.OpenVPN.LogItem; @@ -43,6 +22,11 @@ import de.blinkt.openvpn.core.OpenVpnService; import de.blinkt.openvpn.core.OpenVpnService.LocalBinder; import de.blinkt.openvpn.core.ProfileManager; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Locale; +import java.util.Vector; + public class LogWindow extends ListActivity implements StateListener { private static final String LOGTIMEFORMAT = "logtimeformat"; private static final int START_VPN_CONFIG = 0; @@ -259,28 +243,32 @@ public class LogWindow extends ListActivity implements StateListener { private LogWindowListAdapter ladapter; private TextView mSpeedView; + private void showDisconnectDialog(final OpenVpnService service) { + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle(R.string.title_cancel); + builder.setMessage(R.string.cancel_connection_query); + builder.setNegativeButton(android.R.string.no, null); + builder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { - @Override + @Override + public void onClick(DialogInterface dialog, int which) { + ProfileManager.setConntectedVpnProfileDisconnected(LogWindow.this); + if(service.getManagement()!=null) + service.getManagement().stopVPN(); + } + }); + + builder.show(); + } + + + @Override public boolean onOptionsItemSelected(MenuItem item) { if(item.getItemId()==R.id.clearlog) { ladapter.clearLog(); return true; } else if(item.getItemId()==R.id.cancel){ - Builder builder = new AlertDialog.Builder(this); - builder.setTitle(R.string.title_cancel); - builder.setMessage(R.string.cancel_connection_query); - builder.setNegativeButton(android.R.string.no, null); - builder.setPositiveButton(android.R.string.yes, new OnClickListener() { - - @Override - public void onClick(DialogInterface dialog, int which) { - ProfileManager.setConntectedVpnProfileDisconnected(getApplicationContext()); - if(mService.getManagement()!=null) - mService.getManagement().stopVPN(); - } - }); - - builder.show(); + showDisconnectDialog(mService); return true; } else if(item.getItemId()==R.id.send) { ladapter.shareLog(); @@ -313,7 +301,7 @@ public class LogWindow extends ListActivity implements StateListener { } - @Override + @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.logmenu, menu); @@ -325,9 +313,21 @@ public class LogWindow extends ListActivity implements StateListener { protected void onResume() { super.onResume(); OpenVPN.addStateListener(this); - } - @Override + if (getIntent() !=null && OpenVpnService.DISCONNECT_VPN.equals(getIntent().getAction())) + showDisconnectDialog(mService); + + setIntent(null); + + } + + @Override + protected void onNewIntent(Intent intent) { + super.onNewIntent(intent); + setIntent(intent); + } + + @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == START_VPN_CONFIG && resultCode==RESULT_OK) { String configuredVPN = data.getStringExtra(VpnProfile.EXTRA_PROFILEUUID); @@ -402,7 +402,7 @@ public class LogWindow extends ListActivity implements StateListener { } - @Override + @Override public void updateState(final String status,final String logmessage, final int resid, final ConnectionStatus level) { runOnUiThread(new Runnable() { diff --git a/src/de/blinkt/openvpn/core/DeviceStateReceiver.java b/src/de/blinkt/openvpn/core/DeviceStateReceiver.java index d5029b07..ecdf5c55 100644 --- a/src/de/blinkt/openvpn/core/DeviceStateReceiver.java +++ b/src/de/blinkt/openvpn/core/DeviceStateReceiver.java @@ -13,9 +13,11 @@ import de.blinkt.openvpn.core.OpenVPN.ByteCountListener; import java.util.LinkedList;
+import static de.blinkt.openvpn.core.OpenVPNManagement.pauseReason;
+
public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountListener {
- private int lastNetwork=-1;
- private OpenVPNManagement mManangement;
+ private int lastNetwork = -1;
+ private OpenVPNManagement mManagement;
// Window time in s
private final int TRAFFIC_WINDOW = 60;
@@ -23,10 +25,11 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL private final long TRAFFIC_LIMIT = 64 * 1024;
- connectState network= connectState.DISCONNECTED;
+ connectState network = connectState.DISCONNECTED;
connectState screen = connectState.SHOULDBECONNECTED;
+ connectState userpause = connectState.SHOULDBECONNECTED;
- private String lastStateMsg=null;
+ private String lastStateMsg = null;
enum connectState {
SHOULDBECONNECTED,
@@ -35,8 +38,7 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL }
static class Datapoint {
- private Datapoint(long t, long d)
- {
+ private Datapoint(long t, long d) {
timestamp = t;
data = d;
}
@@ -49,34 +51,49 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL @Override
public void updateByteCount(long in, long out, long diffin, long diffout) {
- if (screen!=connectState.PENDINGDISCONNECT)
+ if (screen != connectState.PENDINGDISCONNECT)
return;
long total = diffin + diffout;
- trafficdata.add(new Datapoint(System.currentTimeMillis(),total));
+ trafficdata.add(new Datapoint(System.currentTimeMillis(), total));
- while(trafficdata.getFirst().timestamp <= (System.currentTimeMillis() - TRAFFIC_WINDOW*1000)) {
+ while (trafficdata.getFirst().timestamp <= (System.currentTimeMillis() - TRAFFIC_WINDOW * 1000)) {
trafficdata.removeFirst();
}
long windowtraffic = 0;
- for (Datapoint dp: trafficdata)
+ for (Datapoint dp : trafficdata)
windowtraffic += dp.data;
- if(windowtraffic < TRAFFIC_LIMIT) {
- screen = connectState.DISCONNECTED;
- OpenVPN.logInfo(R.string.screenoff_pause,
- OpenVpnService.humanReadableByteCount(TRAFFIC_LIMIT, false), TRAFFIC_WINDOW);
+ if (windowtraffic < TRAFFIC_LIMIT) {
+ screen = connectState.DISCONNECTED;
+ OpenVPN.logInfo(R.string.screenoff_pause,
+ OpenVpnService.humanReadableByteCount(TRAFFIC_LIMIT, false), TRAFFIC_WINDOW);
- mManangement.pause();
- }
+ mManagement.pause(getPauseReason());
+ }
}
+ public void userPause(boolean pause) {
+ if (pause) {
+ userpause = connectState.DISCONNECTED;
+ // Check if we should disconnect
+ mManagement.pause(getPauseReason());
+ } else {
+ boolean wereConnected = shouldBeConnected();
+ userpause = connectState.SHOULDBECONNECTED;
+ if (shouldBeConnected() && !wereConnected)
+ mManagement.resume();
+ else
+ // Update the reason why we currently paused
+ mManagement.pause(getPauseReason());
+ }
+ }
public DeviceStateReceiver(OpenVPNManagement magnagement) {
super();
- mManangement = magnagement;
+ mManagement = magnagement;
}
@@ -85,31 +102,36 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
- if(ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
+ if (ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
networkStateChange(context);
} else if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) {
- boolean screenoff = prefs.getBoolean("screenoff", false);
+ boolean screenOff = prefs.getBoolean("screenoff", false);
- if(screenoff) {
- if(!ProfileManager.getLastConnectedVpn().mPersistTun)
+ if (screenOff) {
+ if (!ProfileManager.getLastConnectedVpn().mPersistTun)
OpenVPN.logError(R.string.screen_nopersistenttun);
screen = connectState.PENDINGDISCONNECT;
fillTrafficData();
- if (network == connectState.DISCONNECTED)
+ if (network == connectState.DISCONNECTED || userpause == connectState.DISCONNECTED)
screen = connectState.DISCONNECTED;
}
} else if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) {
// Network was disabled because screen off
- if (screen == connectState.DISCONNECTED && network == connectState.SHOULDBECONNECTED) {
- mManangement.resume();
-
- }
+ boolean connected = shouldBeConnected();
screen = connectState.SHOULDBECONNECTED;
+ /* should be connected has changed because the screen is on now, connect the VPN */
+ if (shouldBeConnected() != connected)
+ mManagement.resume();
+ else
+ /*Update the reason why we are still paused */
+ mManagement.pause(getPauseReason());
+
}
}
+
private void fillTrafficData() {
trafficdata.add(new Datapoint(System.currentTimeMillis(), TRAFFIC_LIMIT));
}
@@ -122,18 +144,18 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL String netstatestring;
- if(networkInfo==null) {
+ if (networkInfo == null) {
netstatestring = "not connected";
- } else {
+ } else {
String subtype = networkInfo.getSubtypeName();
- if(subtype==null)
+ if (subtype == null)
subtype = "";
String extrainfo = networkInfo.getExtraInfo();
- if(extrainfo==null)
- extrainfo="";
+ if (extrainfo == null)
+ extrainfo = "";
/*
- if(networkInfo.getType()==android.net.ConnectivityManager.TYPE_WIFI) {
+ if(networkInfo.getType()==android.net.ConnectivityManager.TYPE_WIFI) {
WifiManager wifiMgr = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiinfo = wifiMgr.getConnectionInfo();
extrainfo+=wifiinfo.getBSSID();
@@ -142,52 +164,71 @@ public class DeviceStateReceiver extends BroadcastReceiver implements ByteCountL }*/
-
- netstatestring = String.format("%2$s %4$s to %1$s %3$s",networkInfo.getTypeName(),
- networkInfo.getDetailedState(),extrainfo,subtype );
+ netstatestring = String.format("%2$s %4$s to %1$s %3$s", networkInfo.getTypeName(),
+ networkInfo.getDetailedState(), extrainfo, subtype);
}
- if(networkInfo!=null && networkInfo.getState() == State.CONNECTED) {
+ if (networkInfo != null && networkInfo.getState() == State.CONNECTED) {
int newnet = networkInfo.getType();
network = connectState.SHOULDBECONNECTED;
- if(sendusr1 && lastNetwork!=newnet) {
+ if (sendusr1 && lastNetwork != newnet) {
if (screen == connectState.PENDINGDISCONNECT)
screen = connectState.DISCONNECTED;
- if (lastNetwork==-1){
- if (screen == connectState.SHOULDBECONNECTED)
- mManangement.resume();
- }else{
- if (screen == connectState.SHOULDBECONNECTED)
- mManangement.reconnect();
+ if (shouldBeConnected()) {
+ if (lastNetwork == -1) {
+ mManagement.resume();
+ } else {
+ mManagement.reconnect();
+ }
}
lastNetwork = newnet;
}
- } else if (networkInfo==null) {
+ } else if (networkInfo == null) {
// Not connected, stop openvpn, set last connected network to no network
- lastNetwork=-1;
- if(sendusr1) {
- mManangement.pause();
+ lastNetwork = -1;
+ if (sendusr1) {
network = connectState.DISCONNECTED;
- // Set screen state to be disconnected if it want to disconnect
+ // Set screen state to be disconnected if disconnect pending
if (screen == connectState.PENDINGDISCONNECT)
screen = connectState.DISCONNECTED;
+
+ mManagement.pause(getPauseReason());
}
}
- if(!netstatestring.equals(lastStateMsg))
+ if (!netstatestring.equals(lastStateMsg))
OpenVPN.logInfo(R.string.netstatus, netstatestring);
- lastStateMsg=netstatestring;
+ lastStateMsg = netstatestring;
+
+ }
+
+ public boolean isUserPaused() {
+ return userpause == connectState.DISCONNECTED;
+ }
+
+ private boolean shouldBeConnected() {
+ return (screen == connectState.SHOULDBECONNECTED && userpause == connectState.SHOULDBECONNECTED &&
+ network == connectState.SHOULDBECONNECTED);
+ }
+
+ private pauseReason getPauseReason() {
+ if (userpause == connectState.DISCONNECTED)
+ return pauseReason.userPause;
+
+ if (screen == connectState.DISCONNECTED)
+ return pauseReason.screenOff;
+ return pauseReason.noNetwork;
}
private NetworkInfo getCurrentNetworkInfo(Context context) {
- ConnectivityManager conn = (ConnectivityManager)
+ ConnectivityManager conn = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
return conn.getActiveNetworkInfo();
diff --git a/src/de/blinkt/openvpn/core/OpenVPN.java b/src/de/blinkt/openvpn/core/OpenVPN.java index 450a13ea..66d985bd 100644 --- a/src/de/blinkt/openvpn/core/OpenVPN.java +++ b/src/de/blinkt/openvpn/core/OpenVPN.java @@ -41,21 +41,17 @@ public class OpenVPN { - public enum ConnectionStatus { - LEVEL_NONETWORK (3), - LEVEL_NOTCONNECTED (4), - LEVEL_AUTH_FAILED (5), - LEVEL_WAITING_FOR_USER_INPUT (6), - LEVEL_CONNECTING_SERVER_REPLIED ( 1), - LEVEL_CONNECTING_NO_SERVER_REPLY_YET (2), - LEVEL_CONNECTED (0), UNKNOWN_LEVEL(-1); - - private final int level; - - ConnectionStatus(int level){ - this.level = level; - } - } + public enum ConnectionStatus { + LEVEL_CONNECTED, + LEVEL_VPNPAUSED, + LEVEL_CONNECTING_SERVER_REPLIED, + LEVEL_CONNECTING_NO_SERVER_REPLY_YET, + LEVEL_NONETWORK, + LEVEL_NOTCONNECTED, + LEVEL_AUTH_FAILED, + LEVEL_WAITING_FOR_USER_INPUT, + UNKNOWN_LEVEL + } public static final byte[] officalkey = {-58, -42, -44, -106, 90, -88, -87, -88, -52, -124, 84, 117, 66, 79, -112, -111, -46, 86, -37, 109}; public static final byte[] officaldebugkey = {-99, -69, 45, 71, 114, -116, 82, 66, -99, -122, 50, -70, -56, -111, 98, -35, -65, 105, 82, 43}; @@ -305,7 +301,22 @@ public class OpenVPN { } - private static ConnectionStatus getLevel(String state){ + public static void updateStatePause(OpenVPNManagement.pauseReason pauseReason) { + switch (pauseReason) { + case noNetwork: + OpenVPN.updateStateString("NONETWORK", "", R.string.state_nonetwork, ConnectionStatus.LEVEL_NONETWORK); + break; + case screenOff: + OpenVPN.updateStateString("SCREENOFF", "", R.string.state_screenoff, ConnectionStatus.LEVEL_VPNPAUSED); + break; + case userPause: + OpenVPN.updateStateString("USERPAUSE", "", R.string.state_userpause, ConnectionStatus.LEVEL_VPNPAUSED); + break; + } + + } + + private static ConnectionStatus getLevel(String state){ String[] noreplyet = {"CONNECTING","WAIT", "RECONNECTING", "RESOLVE", "TCP_CONNECT"}; String[] reply = {"AUTH","GET_CONFIG","ASSIGN_IP","ADD_ROUTES"}; String[] connected = {"CONNECTED"}; diff --git a/src/de/blinkt/openvpn/core/OpenVPNManagement.java b/src/de/blinkt/openvpn/core/OpenVPNManagement.java index 5b8fc074..ce8d38c2 100644 --- a/src/de/blinkt/openvpn/core/OpenVPNManagement.java +++ b/src/de/blinkt/openvpn/core/OpenVPNManagement.java @@ -1,11 +1,17 @@ package de.blinkt.openvpn.core; public interface OpenVPNManagement { - int mBytecountinterval=2; + enum pauseReason { + noNetwork, + userPause, + screenOff + } + + int mBytecountInterval =2; void reconnect(); - void pause(); + void pause(pauseReason reason); void resume(); diff --git a/src/de/blinkt/openvpn/core/OpenVpnManagementThread.java b/src/de/blinkt/openvpn/core/OpenVpnManagementThread.java index 13bebc8a..c4b4f379 100644 --- a/src/de/blinkt/openvpn/core/OpenVpnManagementThread.java +++ b/src/de/blinkt/openvpn/core/OpenVpnManagementThread.java @@ -1,16 +1,5 @@ package de.blinkt.openvpn.core;
-import java.io.FileDescriptor;
-import java.io.IOException;
-import java.io.InputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.util.LinkedList;
-import java.util.Locale;
-import java.util.Vector;
-
import android.content.Context;
import android.content.SharedPreferences;
import android.net.LocalServerSocket;
@@ -23,6 +12,18 @@ import de.blinkt.openvpn.R; import de.blinkt.openvpn.VpnProfile;
import de.blinkt.openvpn.core.OpenVPN.ConnectionStatus;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.Locale;
+import java.util.Vector;
+
public class OpenVpnManagementThread implements Runnable, OpenVPNManagement {
private static final String TAG = "openvpn";
@@ -33,11 +34,13 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { private LocalServerSocket mServerSocket;
private boolean mReleaseHold=true;
private boolean mWaitingForRelease=false;
- private long mLastHoldRelease=0;
+ private long mLastHoldRelease=0;
private static Vector<OpenVpnManagementThread> active=new Vector<OpenVpnManagementThread>();
private LocalSocket mServerSocketLocal;
+ private pauseReason lastPauseReason = pauseReason.noNetwork;
+
public OpenVpnManagementThread(VpnProfile profile, OpenVpnService openVpnService) {
mProfile = profile;
mOpenVPNService = openVpnService;
@@ -50,6 +53,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { }
+
public boolean openManagementInterface(Context c) {
// Could take a while to open connection
int tries=8;
@@ -66,7 +70,9 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { } catch (IOException e) {
// wait 300 ms before retrying
try { Thread.sleep(300);
- } catch (InterruptedException e1) {}
+ } catch (InterruptedException e1) {
+ e1.printStackTrace();
+ }
}
tries--;
@@ -133,11 +139,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { e.printStackTrace();
}
if(fds!=null){
-
- for (FileDescriptor fd : fds) {
-
- mFDList.add(fd);
- }
+ Collections.addAll(mFDList, fds);
}
String input = new String(buffer,0,numbytesread,"UTF-8");
@@ -157,7 +159,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { //! Hack O Rama 2000!
private void protectFileDescriptor(FileDescriptor fd) {
- Exception exp=null;
+ Exception exp;
try {
Method getInt = FileDescriptor.class.getDeclaredMethod("getInt$");
int fdint = (Integer) getInt.invoke(fd);
@@ -181,11 +183,10 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { } catch (NullPointerException e) {
exp =e;
}
- if(exp!=null) {
- exp.printStackTrace();
- Log.d("Openvpn", "Failed to retrieve fd from socket: " + fd);
- OpenVPN.logMessage(0, "", "Failed to retrieve fd from socket: " + exp.getLocalizedMessage());
- }
+
+ exp.printStackTrace();
+ Log.d("Openvpn", "Failed to retrieve fd from socket: " + fd);
+ OpenVPN.logMessage(0, "", "Failed to retrieve fd from socket: " + exp.getLocalizedMessage());
}
private String processInput(String pendingInput) {
@@ -214,6 +215,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { if(cmd.equals("INFO")) {
// Ignore greeting from mgmt
//logStatusMessage(command);
+ ;
}else if (cmd.equals("PASSWORD")) {
processPWCommand(argument);
} else if (cmd.equals("HOLD")) {
@@ -239,6 +241,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { Log.i(TAG, "Got unrecognized command" + command);
}
} else if (command.startsWith("SUCCESS:")) {
+ ;
// ignore
} else {
Log.i(TAG, "Got unrecognized line from managment" + command);
@@ -250,20 +253,25 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { releaseHoldCmd();
} else {
mWaitingForRelease=true;
- OpenVPN.updateStateString("NONETWORK", "",R.string.state_nonetwork,ConnectionStatus.LEVEL_NONETWORK);
+
+ OpenVPN.updateStatePause(lastPauseReason);
+
+
}
}
private void releaseHoldCmd() {
if ((System.currentTimeMillis()- mLastHoldRelease) < 5000) {
try {
Thread.sleep(3000);
- } catch (InterruptedException e) {}
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
}
mWaitingForRelease=false;
mLastHoldRelease = System.currentTimeMillis();
managmentCommand("hold release\n");
- managmentCommand("bytecount " + mBytecountinterval + "\n");
+ managmentCommand("bytecount " + mBytecountInterval + "\n");
managmentCommand("state on\n");
}
@@ -366,7 +374,7 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { }
private boolean sendTunFD (String needed, String extra) {
- Exception exp = null;
+ Exception exp;
if(!extra.equals("tun")) {
// We only support tun
String errmsg = String.format("Devicetype %s requested, but only tun is possible with the Android API, sorry!",extra);
@@ -413,11 +421,10 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { } catch (IOException e) {
exp =e;
}
- if(exp!=null) {
- OpenVPN.logMessage(0,"", "Could not send fd over socket:" + exp.getLocalizedMessage());
- exp.printStackTrace();
- }
- return false;
+ OpenVPN.logMessage(0, "", "Could not send fd over socket:" + exp.getLocalizedMessage());
+ exp.printStackTrace();
+
+ return false;
}
private void processPWCommand(String argument) {
@@ -485,8 +492,13 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { public void signalusr1() {
mReleaseHold=false;
+
if(!mWaitingForRelease)
managmentCommand("signal SIGUSR1\n");
+ else
+ // If signalusr1 is called update the state string
+ // if there is another for stopping
+ OpenVPN.updateStatePause(lastPauseReason);
}
public void reconnect() {
@@ -503,13 +515,16 @@ public class OpenVpnManagementThread implements Runnable, OpenVPNManagement { }
@Override
- public void pause() {
+ public void pause (pauseReason reason) {
+ lastPauseReason = reason;
signalusr1();
}
@Override
public void resume() {
releaseHold();
+ /* Reset the reason why we are disconnected */
+ lastPauseReason = pauseReason.noNetwork;
}
@Override
diff --git a/src/de/blinkt/openvpn/core/OpenVpnService.java b/src/de/blinkt/openvpn/core/OpenVpnService.java index 74ae7245..230ddbaa 100644 --- a/src/de/blinkt/openvpn/core/OpenVpnService.java +++ b/src/de/blinkt/openvpn/core/OpenVpnService.java @@ -9,7 +9,8 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; -import android.net.*; +import android.net.ConnectivityManager; +import android.net.VpnService; import android.os.*; import android.os.Handler.Callback; import android.preference.PreferenceManager; @@ -33,8 +34,12 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac public static final String START_SERVICE_STICKY = "de.blinkt.openvpn.START_SERVICE_STICKY"; public static final String ALWAYS_SHOW_NOTIFICATION = "de.blinkt.openvpn.NOTIFICATION_ALWAYS_VISIBLE"; + public static final String DISCONNECT_VPN = "de.blinkt.openvpn.DISCONNECT_VPN"; + private static final String PAUSE_VPN = "de.blinkt.openvpn.PAUSE_VPN"; + private static final String RESUME_VPN = "de.blinkt.openvpn.RESUME_VPN"; - private Thread mProcessThread=null; + + private Thread mProcessThread=null; private final Vector<String> mDnslist=new Vector<String>(); @@ -60,8 +65,6 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac private static final int OPENVPN_STATUS = 1; - public static final int PROTECT_FD = 0; - private static boolean mNotificationAlwaysVisible =false; private final IBinder mBinder = new LocalBinder(); @@ -111,12 +114,12 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac } } - private void showNotification(String msg, String tickerText, boolean lowpriority, long when, ConnectionStatus level) { + private void showNotification(String msg, String tickerText, boolean lowpriority, long when, ConnectionStatus status) { String ns = Context.NOTIFICATION_SERVICE; NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns); - int icon = getIconByLevel(level); + int icon = getIconByConnectionStatus(status); android.app.Notification.Builder nbuilder = new Notification.Builder(this); @@ -131,6 +134,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac nbuilder.setContentIntent(getLogPendingIntent()); nbuilder.setSmallIcon(icon); + if(when !=0) nbuilder.setWhen(when); @@ -148,7 +152,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac startForeground(OPENVPN_STATUS, notification); } - private int getIconByLevel(ConnectionStatus level) { + private int getIconByConnectionStatus(ConnectionStatus level) { switch (level) { case LEVEL_CONNECTED: case UNKNOWN_LEVEL: @@ -162,6 +166,8 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac return R.drawable.ic_stat_vpn_outline; case LEVEL_CONNECTING_SERVER_REPLIED: return R.drawable.ic_stat_vpn_empty_halo; + case LEVEL_VPNPAUSED: + return android.R.drawable.ic_media_pause; default: return R.drawable.ic_stat_vpn; @@ -181,17 +187,39 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac Method setUsesChronometer = nbuilder.getClass().getMethod("setUsesChronometer", boolean.class); setUsesChronometer.invoke(nbuilder,true); - /* PendingIntent cancelconnet=null; - - nbuilder.addAction(android.R.drawable.ic_menu_close_clear_cancel, - getString(R.string.cancel_connection),cancelconnet); */ } - //ignore exception + Intent disconnectVPN = new Intent(this,LogWindow.class); + disconnectVPN.setAction(DISCONNECT_VPN); + PendingIntent disconnectPendingIntent = PendingIntent.getActivity(this, 0, disconnectVPN, 0); + + nbuilder.addAction(android.R.drawable.ic_menu_close_clear_cancel, + getString(R.string.cancel_connection),disconnectPendingIntent); + + Intent pauseVPN = new Intent(this,OpenVpnService.class); + if (mDeviceStateReceiver == null || !mDeviceStateReceiver.isUserPaused()) { + pauseVPN.setAction(PAUSE_VPN); + PendingIntent pauseVPNPending = PendingIntent.getService(this,0,pauseVPN,0); + nbuilder.addAction(android.R.drawable.ic_media_pause, + getString(R.string.pauseVPN), pauseVPNPending); + + } else { + pauseVPN.setAction(RESUME_VPN); + PendingIntent resumeVPNPending = PendingIntent.getService(this,0,pauseVPN,0); + nbuilder.addAction(android.R.drawable.ic_media_play, + getString(R.string.resumevpn), resumeVPNPending); + } + + + //ignore exception } catch (NoSuchMethodException nsm) { + nsm.printStackTrace(); } catch (IllegalArgumentException e) { + e.printStackTrace(); } catch (IllegalAccessException e) { + e.printStackTrace(); } catch (InvocationTargetException e) { + e.printStackTrace(); } } @@ -241,7 +269,22 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac OpenVPN.addStateListener(this); OpenVPN.addByteCountListener(this); - if(intent != null && intent.getAction() !=null &&intent.getAction().equals(START_SERVICE)) + if(intent != null && intent.getAction() !=null &&intent.getAction().equals(PAUSE_VPN)) + { + if(mDeviceStateReceiver!=null) + mDeviceStateReceiver.userPause(true); + return START_NOT_STICKY; + } + + if(intent != null && intent.getAction() !=null &&intent.getAction().equals(RESUME_VPN)) + { + if(mDeviceStateReceiver!=null) + mDeviceStateReceiver.userPause(false); + return START_NOT_STICKY; + } + + + if(intent != null && intent.getAction() !=null &&intent.getAction().equals(START_SERVICE)) return START_NOT_STICKY; if(intent != null && intent.getAction() !=null &&intent.getAction().equals(START_SERVICE_STICKY)) { return START_REDELIVER_INTENT; @@ -566,9 +609,9 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac if(mDisplayBytecount) { String netstat = String.format(getString(R.string.statusline_bytecount), humanReadableByteCount(in, false), - humanReadableByteCount(diffin/ OpenVPNManagement.mBytecountinterval, true), + humanReadableByteCount(diffin/ OpenVPNManagement.mBytecountInterval, true), humanReadableByteCount(out, false), - humanReadableByteCount(diffout/ OpenVPNManagement.mBytecountinterval, true)); + humanReadableByteCount(diffout/ OpenVPNManagement.mBytecountInterval, true)); boolean lowpriority = !mNotificationAlwaysVisible; showNotification(netstat,null,lowpriority,mConnecttime, LEVEL_CONNECTED); |