summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArne Schwabe <arne@rfc2549.org>2013-06-23 15:09:09 +0200
committerArne Schwabe <arne@rfc2549.org>2013-06-23 15:09:09 +0200
commit180642560ef5c8a0139dcd50c1a7fa949c0c20f4 (patch)
tree89a22ec06b6a6b943a0cf0903a9cebe954d29abe
parent71a288f56eb45be299782cd630b401e32118b8b6 (diff)
Implement expandable notifications for 4.1
-rwxr-xr-xres/values/strings.xml4
-rw-r--r--src/de/blinkt/openvpn/LogWindow.java88
-rw-r--r--src/de/blinkt/openvpn/core/DeviceStateReceiver.java143
-rw-r--r--src/de/blinkt/openvpn/core/OpenVPN.java43
-rw-r--r--src/de/blinkt/openvpn/core/OpenVPNManagement.java10
-rw-r--r--src/de/blinkt/openvpn/core/OpenVpnManagementThread.java83
-rw-r--r--src/de/blinkt/openvpn/core/OpenVpnService.java73
7 files changed, 282 insertions, 162 deletions
diff --git a/res/values/strings.xml b/res/values/strings.xml
index e9bacaee..10074e8a 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -281,5 +281,9 @@
<string name="screenoff_pause">Pausing connection in screen off state: less than %1$s in %2$ss</string>
<string name="screen_nopersistenttun">Warning: Persistent tun not enabled for this VPN. Traffic will use the normal Internet connection when the screen is off.</string>
<string name="save_password">Save Password</string>
+ <string name="pauseVPN">Pause VPN</string>
+ <string name="resumevpn">Resume VPN</string>
+ <string name="state_userpause">VPN pause requested by user</string>
+ <string name="state_screenoff">VPN paused - screen off</string>
</resources> \ No newline at end of file
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);