diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/de/blinkt/openvpn/OpenVPN.java | 53 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/OpenVpnManagementThread.java | 16 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/OpenVpnService.java | 104 | 
3 files changed, 117 insertions, 56 deletions
| diff --git a/src/de/blinkt/openvpn/OpenVPN.java b/src/de/blinkt/openvpn/OpenVPN.java index 8d6cb4c8..9cfaf1e8 100644 --- a/src/de/blinkt/openvpn/OpenVPN.java +++ b/src/de/blinkt/openvpn/OpenVPN.java @@ -15,18 +15,23 @@ public class OpenVPN {  	private static Vector<LogListener> logListener;  	private static Vector<StateListener> stateListener; +	private static Vector<ByteCountListener> byteCountListener; +  	private static String[] mBconfig; -	private static String mLaststatemsg; +	private static String mLaststatemsg=""; -	private static String mLaststate; +	private static String mLaststate = "NOPROCESS";  	private static int mLastStateresid=R.string.state_noprocess; +	 +	private static long mlastByteCount[]={0,0,0,0};  	static {  		logbuffer  = new LinkedList<LogItem>();  		logListener = new Vector<OpenVPN.LogListener>();  		stateListener = new Vector<OpenVPN.StateListener>(); +		byteCountListener = new Vector<OpenVPN.ByteCountListener>();  		logInformation();  	} @@ -83,7 +88,7 @@ public class OpenVPN {  					String str = String.format(Locale.ENGLISH,"Log (no context) resid %d", mRessourceId);  					if(mArgs !=null)  						for(Object o:mArgs) -							str += "|" +  o.toString(); +						str += "|" +  o.toString();  					return str;  				}  			} @@ -107,6 +112,10 @@ public class OpenVPN {  	public interface StateListener {  		void updateState(String state, String logmessage, int localizedResId);  	} +	 +	public interface ByteCountListener { +		void updateByteCount(long in, long out, long diffin, long diffout); +	}  	synchronized static void logMessage(int level,String prefix, String message)  	{ @@ -131,14 +140,25 @@ public class OpenVPN {  	public synchronized static void removeLogListener(LogListener ll) {  		logListener.remove(ll);  	} +	 +	public static void addByteCountListener(ByteCountListener bcl) { +		bcl.updateByteCount(mlastByteCount[0],	mlastByteCount[1], mlastByteCount[2], mlastByteCount[3]); +		byteCountListener.add(bcl); +	}	 +	 +	public static void removeByteCountListener(ByteCountListener bcl) { +		byteCountListener.remove(bcl); +	}  	public synchronized static void addStateListener(StateListener sl){ -		stateListener.add(sl); -		if(mLaststate!=null) -			sl.updateState(mLaststate, mLaststatemsg, mLastStateresid); +		if(!stateListener.contains(sl)){ +			stateListener.add(sl); +			if(mLaststate!=null) +				sl.updateState(mLaststate, mLaststatemsg, mLastStateresid); +		}  	}	 - +	  	private static int getLocalizedState(String state){  		if (state.equals("CONNECTING"))   			return R.string.state_connecting; @@ -199,12 +219,10 @@ public class OpenVPN {  	}  	public synchronized static void updateStateString(String state, String msg, int resid) { -		if (! "BYTECOUNT".equals(state)) { -			mLaststate= state; -			mLaststatemsg = msg; -			mLastStateresid = resid; -		} - +		mLaststate= state; +		mLaststatemsg = msg; +		mLastStateresid = resid; +		  		for (StateListener sl : stateListener) {  			sl.updateState(state,msg,resid);  		} @@ -240,4 +258,13 @@ public class OpenVPN {  		newlogItem(new LogItem(LogItem.ERROR, ressourceId,args));  	} +	public static void updateByteCount(long in, long out, long diffin, long diffout) { +		mlastByteCount = new long[] {in,out,diffin,diffout}; +		for(ByteCountListener bcl:byteCountListener){ +			bcl.updateByteCount(in, out, diffin,diffout); +		} +	} + + +  } diff --git a/src/de/blinkt/openvpn/OpenVpnManagementThread.java b/src/de/blinkt/openvpn/OpenVpnManagementThread.java index 3d68d943..dd3708cf 100644 --- a/src/de/blinkt/openvpn/OpenVpnManagementThread.java +++ b/src/de/blinkt/openvpn/OpenVpnManagementThread.java @@ -290,24 +290,12 @@ public class OpenVpnManagementThread implements Runnable {  		mLastIn=in;
  		mLastOut=out;
 -		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("BYTECOUNT",netstat);
 +		OpenVPN.updateByteCount(in,out,diffin, diffout);
  	}
 -	// 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);
 -	}
 +
  	private void processNeedCommand(String argument) {
  		int p1 =argument.indexOf('\'');
 diff --git a/src/de/blinkt/openvpn/OpenVpnService.java b/src/de/blinkt/openvpn/OpenVpnService.java index 53ae80b1..0ac57406 100644 --- a/src/de/blinkt/openvpn/OpenVpnService.java +++ b/src/de/blinkt/openvpn/OpenVpnService.java @@ -14,9 +14,7 @@   * limitations under the License.   */ -package de.blinkt.openvpn; - -import java.io.IOException; +package de.blinkt.openvpn;import java.io.IOException;  import java.lang.reflect.InvocationTargetException;  import java.lang.reflect.Method;  import java.util.Vector; @@ -34,16 +32,19 @@ import android.net.LocalSocket;  import android.net.LocalSocketAddress;  import android.net.VpnService;  import android.os.Binder; -import android.os.Handler; -import android.os.Handler.Callback;  import android.os.Build; +import android.os.Handler.Callback;  import android.os.IBinder;  import android.os.Message;  import android.os.ParcelFileDescriptor; +  import de.blinkt.openvpn.OpenVPN.StateListener;  public class OpenVpnService extends VpnService implements StateListener, Callback {  	public static final String START_SERVICE = "de.blinkt.openvpn.START_SERVICE"; +	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"; +  	private Thread mProcessThread=null; @@ -76,15 +77,22 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac  	public static final int PROTECT_FD = 0; + +	private static final int LEVEL_OFFLINE = 0; +	private static final int LEVEL_NOTCONNECTED = 1; +	private static final int LEVEL_CONNECTED = 2; + +	private static boolean mNotificationalwaysVisible=false; +  	private final IBinder mBinder = new LocalBinder(); -	 +  	public class LocalBinder extends Binder {  		public OpenVpnService getService() { -            // Return this instance of LocalService so clients can call public methods -            return OpenVpnService.this; -        } -    } -	 +			// Return this instance of LocalService so clients can call public methods +			return OpenVpnService.this; +		} +	} +  	@Override  	public IBinder onBind(Intent intent) {  		String action = intent.getAction(); @@ -93,7 +101,7 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac  		else  			return super.onBind(intent);  	} -	 +  	@Override  	public void onRevoke() {  		OpenVpnManagementThread.stopOpenVPN(); @@ -115,27 +123,31 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac  		}  	} -	private void showNotification(String msg, String tickerText, boolean lowpriority, long when) { +	private void showNotification(String msg, String tickerText, boolean lowpriority, long when, int level) {  		String ns = Context.NOTIFICATION_SERVICE;  		NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns); -		int icon = R.drawable.ic_stat_vpn; +		int icon = R.drawable.notification_icon;  		android.app.Notification.Builder nbuilder = new Notification.Builder(this); -		nbuilder.setContentTitle(getString(R.string.notifcation_title,mProfile.mName)); +		if(mProfile!=null) +			nbuilder.setContentTitle(getString(R.string.notifcation_title,mProfile.mName)); +		else +			nbuilder.setContentTitle(getString(R.string.notifcation_title_notconnect)); +  		nbuilder.setContentText(msg);  		nbuilder.setOnlyAlertOnce(true);  		nbuilder.setOngoing(true);  		nbuilder.setContentIntent(getLogPendingIntent()); -		nbuilder.setSmallIcon(icon); +		nbuilder.setSmallIcon(icon,level);  		if(when !=0)  			nbuilder.setWhen(when);  		// Try to set the priority available since API 16 (Jellybean)  		jbNotificationExtras(lowpriority, nbuilder); -		if(tickerText!=null) +		if(tickerText!=null && !tickerText.equals(""))  			nbuilder.setTicker(tickerText);  		@SuppressWarnings("deprecation") @@ -220,11 +232,19 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac  	@Override -	public int onStartCommand(Intent intent, int flags, int startId) {		 -		 +	public int onStartCommand(Intent intent, int flags, int startId) { + +		if(intent != null && intent.getBooleanExtra(ALWAYS_SHOW_NOTIFICATION, false)) +			mNotificationalwaysVisible=true; + +		OpenVPN.addStateListener(this); +  		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; +		} +  		// Extract information from the intent.  		String prefix = getPackageName(); @@ -234,10 +254,9 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac  		mProfile = ProfileManager.get(profileUUID); -		showNotification("Starting VPN " + mProfile.mName,"Starting VPN " + mProfile.mName, false,0); +		showNotification("Starting VPN " + mProfile.mName,"Starting VPN " + mProfile.mName, false,0,LEVEL_NOTCONNECTED); -		OpenVPN.addStateListener(this);  		// Set a flag that we are starting a new VPN  		mStarting=true; @@ -469,20 +488,23 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac  	public void updateState(String state,String logmessage, int resid) {  		// If the process is not running, ignore any state,   		// Notification should be invisible in this state -		if(mProcessThread==null) +		if(mProcessThread==null && !mNotificationalwaysVisible)  			return;  		// Display byte count only after being connected -		if("BYTECOUNT".equals(state)) { -			if(mDisplayBytecount) { -				showNotification(logmessage,null,true,mConnecttime); -			} -		} else { +		{ +			int level;  			if("CONNECTED".equals(state)) {  				mDisplayBytecount = true;  				mConnecttime = System.currentTimeMillis(); +				level = LEVEL_CONNECTED;  			} else { +				if ("NONETWORK".equals(state)) { +					level = LEVEL_OFFLINE; +				} else { +					level = LEVEL_NOTCONNECTED; +				}  				mDisplayBytecount = false;  			} @@ -490,11 +512,35 @@ public class OpenVpnService extends VpnService implements StateListener, Callbac  			// This also mean we are no longer connected, ignore bytecount messages until next  			// CONNECTED  			String ticker = getString(resid); -			showNotification(getString(resid) +" " + logmessage,ticker,false,0); +			showNotification(getString(resid) +" " + logmessage,ticker,false,0, level);  		}  	} + +	public void updateByteCount(long in, long out, long diffin, long diffout) { +		if(mDisplayBytecount) { +			String netstat = String.format(getString(R.string.statusline_bytecount), +					humanReadableByteCount(in, false), +					humanReadableByteCount(diffin, false), +					humanReadableByteCount(out, false), +					humanReadableByteCount(diffout, false)); + +			boolean lowpriority = !mNotificationalwaysVisible; +			showNotification(netstat,null,lowpriority,mConnecttime, LEVEL_CONNECTED); +		} + +	} + +	// 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); +	} +  	@Override  	public boolean handleMessage(Message msg) {  		Runnable r = msg.getCallback(); | 
