summaryrefslogtreecommitdiff
path: root/src/de/blinkt/openvpn
diff options
context:
space:
mode:
authorArne Schwabe <arne@rfc2549.org>2012-06-18 00:27:03 +0200
committerArne Schwabe <arne@rfc2549.org>2012-06-18 00:27:03 +0200
commit421141e64541a0c6f30b11304209f90545926a4b (patch)
tree6bd879fc55012fcbe50467be259ea026d38b33ac /src/de/blinkt/openvpn
parent6a3b2e74504b1377db6a5a8f1d7a5080001d3047 (diff)
Add a status message which shows the status of the connecting/connected VPN
Diffstat (limited to 'src/de/blinkt/openvpn')
-rw-r--r--src/de/blinkt/openvpn/LaunchVPN.java60
-rw-r--r--src/de/blinkt/openvpn/LogWindow.java4
-rw-r--r--src/de/blinkt/openvpn/NetworkSateReceiver.java1
-rw-r--r--src/de/blinkt/openvpn/OpenVPN.java16
-rw-r--r--src/de/blinkt/openvpn/OpenVPNThread.java2
-rw-r--r--src/de/blinkt/openvpn/OpenVpnManagementThread.java40
-rw-r--r--src/de/blinkt/openvpn/OpenVpnService.java68
7 files changed, 128 insertions, 63 deletions
diff --git a/src/de/blinkt/openvpn/LaunchVPN.java b/src/de/blinkt/openvpn/LaunchVPN.java
index e76057d7..1c873f22 100644
--- a/src/de/blinkt/openvpn/LaunchVPN.java
+++ b/src/de/blinkt/openvpn/LaunchVPN.java
@@ -44,7 +44,6 @@ import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
-import android.widget.Toast;
/**
* This Activity actually handles two stages of a launcher shortcut's life cycle.
@@ -80,11 +79,11 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener {
private ProfileManager mPM;
private VpnProfile mSelectedProfile;
-
-
+
+
private boolean mCmfixed=false;
static boolean minivpnwritten=false;
-
+
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
@@ -92,7 +91,7 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener {
mPM =ProfileManager.getInstance(this);
}
-
+
@Override
protected void onStart() {
super.onStart();
@@ -100,6 +99,7 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener {
final Intent intent = getIntent();
final String action = intent.getAction();
+
// If the intent is a request to create a shortcut, we'll do that and exit
if(Intent.ACTION_MAIN.equals(action)) {
@@ -110,10 +110,11 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener {
VpnProfile profileToConnect = ProfileManager.get(shortcutUUID);
if(shortcutName != null && profileToConnect ==null)
profileToConnect = ProfileManager.getInstance(this).getProfileByName(shortcutName);
-
+
if(profileToConnect ==null) {
- Toast notfound = Toast.makeText(this, R.string.shortcut_profile_notfound, Toast.LENGTH_SHORT);
- notfound.show();
+ OpenVPN.logError(R.string.shortcut_profile_notfound);
+ // show Log window to display error
+ showLogWindow();
finish();
return;
}
@@ -221,31 +222,31 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener {
// }
}
-
+
private boolean writeMiniVPN() {
File mvpnout = new File(getCacheDir(),"minivpn");
if (mvpnout.exists() && mvpnout.canExecute())
return true;
-
+
if(minivpnwritten)
return true;
try {
InputStream mvpn = getAssets().open("minivpn");
-
+
FileOutputStream fout = new FileOutputStream(mvpnout);
-
+
byte buf[]= new byte[4096];
-
+
int lenread = mvpn.read(buf);
while(lenread> 0) {
fout.write(buf, 0, lenread);
lenread = mvpn.read(buf);
}
fout.close();
-
+
if(!mvpnout.setExecutable(true))
return false;
-
+
minivpnwritten=true;
return true;
} catch (IOException e) {
@@ -303,26 +304,36 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener {
if(needpw !=0) {
askForPW(needpw);
} else {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+ boolean showlogwindow = prefs.getBoolean("showlogwindow", false);
+ if(showlogwindow)
+ showLogWindow();
new startOpenVpnThread().start();
}
-
} else if (resultCode == Activity.RESULT_CANCELED) {
// User does not want us to start, so we just vanish
finish();
}
}
}
+ void showLogWindow() {
+
+ Intent startLW = new Intent(getBaseContext(),LogWindow.class);
+ startLW.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
+ startActivity(startLW);
+
+ }
void showConfigErrorDialog(int vpnok) {
AlertDialog.Builder d = new AlertDialog.Builder(this);
d.setTitle(R.string.config_error_found);
d.setMessage(vpnok);
d.setPositiveButton(android.R.string.ok, new OnClickListener() {
-
+
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
-
+
}
});
d.show();
@@ -339,7 +350,7 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener {
// Check if we want to fix /dev/tun
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean usecm9fix = prefs.getBoolean("useCM9Fix", false);
-
+
if(usecm9fix && !mCmfixed ) {
ProcessBuilder pb = new ProcessBuilder(new String[] {"su","-c","chown system /dev/tun"});
try {
@@ -353,8 +364,8 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener {
e.printStackTrace();
}
}
-
-
+
+
if (intent != null) {
// Start the query
@@ -363,7 +374,8 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener {
} catch (ActivityNotFoundException ane) {
// Shame on you Sony! At least one user reported that
// an official Sony Xperia Arc S image triggers this exception
- Toast.makeText(this, R.string.no_vpn_support_image, Toast.LENGTH_LONG).show();
+ OpenVPN.logError(R.string.no_vpn_support_image);
+ showLogWindow();
}
} else {
onActivityResult(START_VPN_PROFILE, Activity.RESULT_OK, null);
@@ -379,10 +391,6 @@ public class LaunchVPN extends ListActivity implements OnItemClickListener {
}
void startOpenVpn() {
- Intent startLW = new Intent(getBaseContext(),LogWindow.class);
- startLW.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
- startActivity(startLW);
-
if(!writeMiniVPN()) {
OpenVPN.logMessage(0, "", "Error writing minivpn binary");
return;
diff --git a/src/de/blinkt/openvpn/LogWindow.java b/src/de/blinkt/openvpn/LogWindow.java
index 6060e7ad..8fadf3ad 100644
--- a/src/de/blinkt/openvpn/LogWindow.java
+++ b/src/de/blinkt/openvpn/LogWindow.java
@@ -271,12 +271,12 @@ public class LogWindow extends ListActivity implements StateListener {
}
@Override
- public void updateState(final String logmessage) {
+ public void updateState(final String status,final String logmessage) {
runOnUiThread(new Runnable() {
@Override
public void run() {
- mSpeedView.setText(logmessage);
+ mSpeedView.setText(status + " " + logmessage);
}
});
diff --git a/src/de/blinkt/openvpn/NetworkSateReceiver.java b/src/de/blinkt/openvpn/NetworkSateReceiver.java
index a8d69896..0758cf3a 100644
--- a/src/de/blinkt/openvpn/NetworkSateReceiver.java
+++ b/src/de/blinkt/openvpn/NetworkSateReceiver.java
@@ -26,7 +26,6 @@ public class NetworkSateReceiver extends BroadcastReceiver {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean sendusr1 = prefs.getBoolean("netchangereconnect", true);
-
String netstatestring;
if(networkInfo==null)
netstatestring = "not connected";
diff --git a/src/de/blinkt/openvpn/OpenVPN.java b/src/de/blinkt/openvpn/OpenVPN.java
index b09eb60e..c23ee56d 100644
--- a/src/de/blinkt/openvpn/OpenVPN.java
+++ b/src/de/blinkt/openvpn/OpenVPN.java
@@ -41,6 +41,12 @@ public class OpenVPN {
}
+ public LogItem(int loglevel, int ressourceId) {
+ mRessourceId =ressourceId;
+ mLevel = loglevel;
+ }
+
+
String getString(Context c) {
if(mMessage !=null) {
return mMessage;
@@ -73,7 +79,7 @@ public class OpenVPN {
}
public interface StateListener {
- void updateState(String logmessage);
+ void updateState(String state, String logmessage);
}
synchronized static void logMessage(int level,String prefix, String message)
@@ -126,9 +132,9 @@ public class OpenVPN {
}
- public static void updateStateString(String msg) {
+ public static void updateStateString(String state, String msg) {
for (StateListener sl : stateListener) {
- sl.updateState(msg);
+ sl.updateState(state,msg);
}
}
@@ -155,6 +161,10 @@ public class OpenVPN {
}
+ public static void logError(int ressourceId) {
+ newlogItem(new LogItem(LogItem.ERROR, ressourceId));
+ }
+
}
diff --git a/src/de/blinkt/openvpn/OpenVPNThread.java b/src/de/blinkt/openvpn/OpenVPNThread.java
index fdb0ac02..22a08763 100644
--- a/src/de/blinkt/openvpn/OpenVPNThread.java
+++ b/src/de/blinkt/openvpn/OpenVPNThread.java
@@ -41,7 +41,7 @@ public class OpenVPNThread implements Runnable {
//mInterface = null;
- OpenVPN.updateStateString("No process running");
+ OpenVPN.updateStateString("NOPROCESS","No process running");
// Not a good place to do it, but will do
OpenVPN.logBuilderConfig(null);
Log.i(TAG, "Exiting");
diff --git a/src/de/blinkt/openvpn/OpenVpnManagementThread.java b/src/de/blinkt/openvpn/OpenVpnManagementThread.java
index 012e0923..f23d9d9b 100644
--- a/src/de/blinkt/openvpn/OpenVpnManagementThread.java
+++ b/src/de/blinkt/openvpn/OpenVpnManagementThread.java
@@ -21,7 +21,8 @@ public class OpenVpnManagementThread implements Runnable {
private LinkedList<FileDescriptor> mFDList=new LinkedList<FileDescriptor>();
private int mBytecountinterval=2;
private long mLastIn=0;
- private long mLastOut=0;
+ private long mLastOut=0;
+ private String mCurrentstate;
private static Vector<OpenVpnManagementThread> active=new Vector<OpenVpnManagementThread>();
@@ -185,8 +186,9 @@ public class OpenVpnManagementThread implements Runnable {
}
private void processState(String argument) {
- String[] args = argument.split(",",2);
- OpenVPN.updateStateString(args[1]);
+ String[] args = argument.split(",",3);
+ mCurrentstate = args[1];
+ OpenVPN.updateStateString(mCurrentstate,args[2]);
}
@@ -195,32 +197,32 @@ public class OpenVpnManagementThread implements Runnable {
int comma = argument.indexOf(',');
long in = Long.parseLong(argument.substring(0, comma));
long out = Long.parseLong(argument.substring(comma+1));
-
+
long diffin = in - mLastIn;
long diffout = out - mLastOut;
-
+
mLastIn=in;
mLastOut=out;
-
- String netstat = String.format("In: %8s, %8s/s Out %8s, %8s/s ",
+
+ String netstat = String.format("In: %8s, %8s/s Out %8s, %8s/s",
humanReadableByteCount(in, false),
humanReadableByteCount(diffin, false),
humanReadableByteCount(out, false),
humanReadableByteCount(diffout, false));
- OpenVPN.updateStateString(netstat);
-
-
+ OpenVPN.updateStateString("BYTECOUNT",netstat);
+
+
}
// From: http://stackoverflow.com/questions/3758606/how-to-convert-byte-size-into-human-readable-format-in-java
public static String humanReadableByteCount(long bytes, boolean si) {
- int unit = si ? 1000 : 1024;
- if (bytes < unit) return bytes + " B";
- int exp = (int) (Math.log(bytes) / Math.log(unit));
- String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp-1) + (si ? "" : "i");
- return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
+ int unit = si ? 1000 : 1024;
+ if (bytes < unit) return bytes + " B";
+ int exp = (int) (Math.log(bytes) / Math.log(unit));
+ String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp-1) + (si ? "" : "i");
+ return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
}
-
+
private void processNeedCommand(String argument) {
int p1 =argument.indexOf('\'');
int p2 = argument.indexOf('\'',p1+1);
@@ -328,10 +330,10 @@ public class OpenVpnManagementThread implements Runnable {
private void processPWCommand(String argument) {
//argument has the form Need 'Private Key' password
-
+
String needed;
try{
-
+
int p1 = argument.indexOf('\'');
int p2 = argument.indexOf('\'',p1+1);
needed = argument.substring(p1+1, p2);
@@ -384,7 +386,7 @@ public class OpenVpnManagementThread implements Runnable {
public void reconnect() {
managmentCommand("signal SIGUSR1\n");
-
+
}
}
diff --git a/src/de/blinkt/openvpn/OpenVpnService.java b/src/de/blinkt/openvpn/OpenVpnService.java
index 8c172115..a0d7503d 100644
--- a/src/de/blinkt/openvpn/OpenVpnService.java
+++ b/src/de/blinkt/openvpn/OpenVpnService.java
@@ -19,19 +19,24 @@ package de.blinkt.openvpn;
import java.io.IOException;
import java.util.Vector;
+import de.blinkt.openvpn.OpenVPN.StateListener;
+
import android.app.Notification;
+import android.app.Notification.Builder;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.LocalSocket;
import android.net.LocalSocketAddress;
import android.net.VpnService;
import android.os.ParcelFileDescriptor;
+import android.preference.PreferenceManager;
-public class OpenVpnService extends VpnService {
+public class OpenVpnService extends VpnService implements StateListener {
private Thread mServiceThread;
private Vector<String> mDnslist=new Vector<String>();
@@ -54,7 +59,9 @@ public class OpenVpnService extends VpnService {
private NetworkSateReceiver mNetworkStateReceiver;
- private static final int HELLO_ID = 1;
+ private boolean mDisplayBytecount=false;
+
+ private static final int OPENVPN_STATUS = 1;
@Override
public void onRevoke() {
@@ -63,24 +70,36 @@ public class OpenVpnService extends VpnService {
stopSelf();
};
- private void showNotification() {
+ private void hideNotification() {
+ String ns = Context.NOTIFICATION_SERVICE;
+ NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
+ mNotificationManager.cancel(OPENVPN_STATUS);
+
+ }
+ private void showNotification(String msg) {
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
int icon = R.drawable.icon;
- CharSequence tickerText = "Hello";
long when = System.currentTimeMillis();
+
+ android.app.Notification.Builder nbuilder = new Notification.Builder(this);
- mNotification = new Notification(icon, tickerText, when);
+ nbuilder.setContentTitle("OpenVPN - " + mProfile.mName);
+ nbuilder.setContentText(msg);
+ nbuilder.setOnlyAlertOnce(true);
+ nbuilder.setOngoing(true);
+ nbuilder.setContentIntent(getLogPendingIntent());
+ nbuilder.setSmallIcon(icon);
+ nbuilder.setWhen(when);
- Context context = getApplicationContext();
- CharSequence contentTitle = "My notification";
- CharSequence contentText = "Hello World!";
+ mNotification = nbuilder.getNotification();
- mNotification.setLatestEventInfo(context, contentTitle, contentText, getLogPendingIntent());
- mNotificationManager.notify(HELLO_ID, mNotification);
+
+
+ mNotificationManager.notify(OPENVPN_STATUS, mNotification);
}
@@ -135,7 +154,7 @@ public class OpenVpnService extends VpnService {
String profileUUID = intent.getStringExtra(prefix + ".profileUUID");
mProfile = ProfileManager.get(profileUUID);
- //showNotification();
+ OpenVPN.addSpeedListener(this);
// Stop the previous session by interrupting the thread.
if(OpenVpnManagementThread.stopOpenVPN()){
@@ -357,4 +376,31 @@ public class OpenVpnService extends VpnService {
mLocalIPv6 = ipv6addr;
}
+ @Override
+ public void updateState(String state,String logmessage) {
+ if("NOPROCESS".equals(state)) {
+ hideNotification();
+ mDisplayBytecount=false;
+ return;
+ }
+
+ if("CONNECTED".equals(state)) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
+ mDisplayBytecount = prefs.getBoolean("statusafterconnect", false);
+ if(!mDisplayBytecount) {
+ hideNotification();
+ return;
+ }
+ }
+
+ if("BYTECOUNT".equals(state)) {
+ if(mDisplayBytecount) {
+ showNotification(logmessage);
+ }
+ } else {
+ // Other notifications are shown
+ showNotification(state +" " + logmessage);
+ }
+ }
+
}