diff options
| author | Arne Schwabe <arne@rfc2549.org> | 2012-12-24 07:47:50 +0100 | 
|---|---|---|
| committer | Arne Schwabe <arne@rfc2549.org> | 2012-12-24 07:47:50 +0100 | 
| commit | 3dbb55fe35b12e5fcbf38e7ecf8de043b16327de (patch) | |
| tree | 31606652e4f498a74912edc9727635fb13a9b035 | |
| parent | 174a0c8a3807df22ebd5731e139c0f0bb511f85b (diff) | |
Make send mini dump work with non Gmail Mail app, make google sending better placed
| -rw-r--r-- | AndroidManifest.xml | 5 | ||||
| -rw-r--r-- | openvpn/Android.mk | 2 | ||||
| -rw-r--r-- | openvpn/src/openvpn/breakpad.cpp | 29 | ||||
| -rw-r--r-- | openvpn/src/openvpn/breakpad.h | 13 | ||||
| -rw-r--r-- | openvpn/src/openvpn/error.c | 7 | ||||
| -rw-r--r-- | openvpn/src/openvpn/openvpn.c | 10 | ||||
| -rw-r--r-- | openvpn/src/openvpn/socket.c | 2 | ||||
| -rw-r--r-- | res/menu/logmenu.xml | 6 | ||||
| -rwxr-xr-x | res/values/strings.xml | 3 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/FileProvider.java | 206 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/LogWindow.java | 70 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/MainActivity.java | 14 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/OpenVPN.java | 58 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/OpenVPNThread.java | 21 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/OpenVpnManagementThread.java | 10 | ||||
| -rw-r--r-- | src/de/blinkt/openvpn/SendDumpActivity.java | 60 | 
16 files changed, 314 insertions, 202 deletions
| diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 8ccd1e96..564d4396 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -43,6 +43,7 @@          <activity              android:name=".LogWindow"              android:label="@string/openvpn_log" /> +        <activity android:name=".SendDumpActivity" />          <activity android:name=".FileSelect" />          <activity android:name=".MainActivity" >              <intent-filter> @@ -121,8 +122,8 @@          <provider              android:name=".FileProvider"              android:authorities="de.blinkt.openvpn.FileProvider" -            android:grantUriPermissions="true" -            android:exported="true" /> +            android:exported="true" +            android:grantUriPermissions="true" />      </application>  </manifest>
\ No newline at end of file diff --git a/openvpn/Android.mk b/openvpn/Android.mk index 6307e5e0..c68bcccf 100644 --- a/openvpn/Android.mk +++ b/openvpn/Android.mk @@ -91,7 +91,7 @@ LOCAL_SRC_FILES:= \  	src/openvpn/status.c \  	src/openvpn/tun.c    ifneq ($(TARGET_ARCH),mips) -LOCAL_SRC_FILES+=../jni/icsandroid.cpp +LOCAL_SRC_FILES+=src/openvpn/breakpad.cpp  endif diff --git a/openvpn/src/openvpn/breakpad.cpp b/openvpn/src/openvpn/breakpad.cpp new file mode 100644 index 00000000..cfcc10a8 --- /dev/null +++ b/openvpn/src/openvpn/breakpad.cpp @@ -0,0 +1,29 @@ + +#include "breakpad.h" +#include "client/linux/handler/exception_handler.h" + + +static +bool DumpCallback(const google_breakpad::MinidumpDescriptor& descriptor, +                  void* context, +                  bool succeeded) { +    printf("Dump path: %s\n", descriptor.path()); +    fflush(stdout); +    fflush(stderr); +    return succeeded; +} + +static google_breakpad::MinidumpDescriptor* desc; +static google_breakpad::ExceptionHandler* eh; + +void breakpad_setup(void) +{ +    printf("Initializing Google Breakpad!\n"); +    desc = new google_breakpad::MinidumpDescriptor("/data/data/de.blinkt.openvpn/cache"); +    eh = new google_breakpad::ExceptionHandler(*desc, NULL, DumpCallback, NULL, true,-1); +} + +void breakpad_dodump(void) +{ +    eh->WriteMinidump(); +} diff --git a/openvpn/src/openvpn/breakpad.h b/openvpn/src/openvpn/breakpad.h new file mode 100644 index 00000000..84df62ab --- /dev/null +++ b/openvpn/src/openvpn/breakpad.h @@ -0,0 +1,13 @@ +#ifndef BUFFER_H +#define BUFFER_H + +#ifdef __cplusplus +extern "C" { +#endif +    void breakpad_setup(void); +    void breakpad_dodump(void); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/openvpn/src/openvpn/error.c b/openvpn/src/openvpn/error.c index ebe9a52d..98611a1b 100644 --- a/openvpn/src/openvpn/error.c +++ b/openvpn/src/openvpn/error.c @@ -57,6 +57,10 @@  #endif  #endif +#ifdef GOOGLE_BREAKPAD +#include "breakpad.h" +#endif +  /* Globals */  unsigned int x_debug_level; /* GLOBAL */ @@ -399,6 +403,9 @@ dont_mute (unsigned int flags)  void  assert_failed (const char *filename, int line)  { +#ifdef GOOGLE_BREAKPAD +    breakpad_dodump(); +#endif    msg (M_FATAL, "Assertion failed at %s:%d", filename, line);  } diff --git a/openvpn/src/openvpn/openvpn.c b/openvpn/src/openvpn/openvpn.c index 4bae5274..a177d9e8 100644 --- a/openvpn/src/openvpn/openvpn.c +++ b/openvpn/src/openvpn/openvpn.c @@ -41,6 +41,10 @@  #define P2P_CHECK_SIG() EVENT_LOOP_CHECK_SIGNAL (c, process_signal_p2p, c); +#ifdef GOOGLE_BREAKPAD +#include "breakpad.h" +#endif +  static bool  process_signal_p2p (struct context *c)  { @@ -321,12 +325,10 @@ wmain (int argc, wchar_t *wargv[]) {  #else  int  main (int argc, char *argv[]) { -#ifdef TARGET_ANDROID  #ifdef GOOGLE_BREAKPAD -#include "../jni/icsandroid.h" -    setup_breakpad(); -#endif +    breakpad_setup();  #endif +  	return openvpn_main(argc, argv);  }  #endif diff --git a/openvpn/src/openvpn/socket.c b/openvpn/src/openvpn/socket.c index 29a15a63..9a33197c 100644 --- a/openvpn/src/openvpn/socket.c +++ b/openvpn/src/openvpn/socket.c @@ -1255,7 +1255,7 @@ resolve_remote (struct link_socket *sock,  	  if (remote_dynamic)  	    *remote_dynamic = NULL;  	} -      else +      /*      else, quick hack to fix persistent-remote ....*/  	{            CLEAR (sock->info.lsa->actual);            if(sock->info.lsa->current_remote) diff --git a/res/menu/logmenu.xml b/res/menu/logmenu.xml index ec2997b0..bb810df0 100644 --- a/res/menu/logmenu.xml +++ b/res/menu/logmenu.xml @@ -1,12 +1,6 @@  <?xml version="1.0" encoding="utf-8"?>
  <menu xmlns:android="http://schemas.android.com/apk/res/android" >
      <item
 -        android:id="@+id/minidump"
 -        android:icon="@android:drawable/ic_menu_upload"
 -        android:showAsAction="ifRoom|withText"
 -        android:title="Send Minidump to developer"
 -        android:titleCondensed="Send Minidump"/>
 -    <item
          android:id="@+id/clearlog"
          android:icon="@drawable/ic_menu_trash_holo_light"
          android:showAsAction="ifRoom|withText"
 diff --git a/res/values/strings.xml b/res/values/strings.xml index eea81d8b..3613c7d1 100755 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -236,5 +236,8 @@      <string name="reconnection_settings">Reconnection settings</string>      <string name="connectretrymessage">Number of seconds to wait between connection attempts.</string>      <string name="connectretrywait">Seconds between connections</string> +    <string name="minidump_generated">OpenVPN crashed unexpectedly. Please consider using the send Minidump option in the main menu</string> +    <string name="send_minidump">Send Minidump to developer</string> +    <string name="send_minidump_summary">Send debugging information about last crash to developer</string>  </resources> diff --git a/src/de/blinkt/openvpn/FileProvider.java b/src/de/blinkt/openvpn/FileProvider.java index 1147ccf0..e86b544f 100644 --- a/src/de/blinkt/openvpn/FileProvider.java +++ b/src/de/blinkt/openvpn/FileProvider.java @@ -24,13 +24,15 @@ import java.io.IOException;  import java.io.InputStream;  import android.content.ContentProvider; -import android.content.ContentValues;  import android.content.ContentProvider.PipeDataWriter; +import android.content.ContentValues;  import android.content.res.AssetFileDescriptor;  import android.database.Cursor; +import android.database.MatrixCursor;  import android.net.Uri;  import android.os.Bundle;  import android.os.ParcelFileDescriptor; +import android.provider.OpenableColumns;  import android.util.Log;  /** @@ -38,92 +40,118 @@ import android.util.Log;   * our .apk.   */  public class FileProvider extends ContentProvider -        implements PipeDataWriter<InputStream> { -    @Override -    public boolean onCreate() { -        return true; -    } - -    @Override -    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, -            String sortOrder) { -        // Don't support queries. -        return null; -    } - -    @Override -    public Uri insert(Uri uri, ContentValues values) { -        // Don't support inserts. -        return null; -    } - -    @Override -    public int delete(Uri uri, String selection, String[] selectionArgs) { -        // Don't support deletes. -        return 0; -    } - -    @Override -    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { -        // Don't support updates. -        return 0; -    } - -    @Override -    public String getType(Uri uri) { -        // For this sample, assume all files are .apks. -        return "application/octet-stream"; -    } - -    @Override -    public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException { -        // Try to open an asset with the given name. -    	String path = uri.getPath(); -    	if(path.startsWith("/")) -    		path = path.replaceFirst("/", "");        -    	 -    	// I think this already random enough, no need for magic secure cookies -    	// 1f9563a4-a1f5-2165-255f2219-111823ef.dmp -    	if (!path.matches("^[0-9a-z-.]*$")) -    		throw new FileNotFoundException("url not in expect format " + uri); - -        try { -        	 -        	File cachedir = getContext().getCacheDir(); -        	File dumpfile = new File(cachedir,path); -            InputStream is = new FileInputStream(dumpfile); -            // Start a new thread that pipes the stream data back to the caller. -            return new AssetFileDescriptor( -                    openPipeHelper(uri, null, null, is, this), 0, -                    dumpfile.length()); -        } catch (IOException e) { -            FileNotFoundException fnf = new FileNotFoundException("Unable to open minidump " + uri); -            throw fnf; -        } -    } - -    @Override -    public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String mimeType, -            Bundle opts, InputStream args) { -        // Transfer data from the asset to the pipe the client is reading. -        byte[] buffer = new byte[8192]; -        int n; -        FileOutputStream fout = new FileOutputStream(output.getFileDescriptor()); -        try { -            while ((n=args.read(buffer)) >= 0) { -                fout.write(buffer, 0, n); -            } -        } catch (IOException e) { -            Log.i("OpenVPNFileProvider", "Failed transferring", e); -        } finally { -            try { -                args.close(); -            } catch (IOException e) { -            } -            try { -                fout.close(); -            } catch (IOException e) { -            } -        } -    } +implements PipeDataWriter<InputStream> { +	@Override +	public boolean onCreate() { +		return true; +	} + +	@Override +	public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, +			String sortOrder) { +		try { +			File dumpfile = getFileFromURI(uri); + + +			MatrixCursor c = new MatrixCursor(projection); + +			Object[] row = new Object[projection.length]; +			int i=0; +			for (String r:projection) { +				if(r.equals(OpenableColumns.SIZE)) +					row[i] = dumpfile.length(); +				if(r.equals(OpenableColumns.DISPLAY_NAME)) +					row[i] = dumpfile.getName(); +				i++; +			} +			c.addRow(row); +			return c; +		} catch (FileNotFoundException e) { +			e.printStackTrace(); +			return null; +		} + + +	} + +	@Override +	public Uri insert(Uri uri, ContentValues values) { +		// Don't support inserts. +		return null; +	} + +	@Override +	public int delete(Uri uri, String selection, String[] selectionArgs) { +		// Don't support deletes. +		return 0; +	} + +	@Override +	public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { +		// Don't support updates. +		return 0; +	} + +	@Override +	public String getType(Uri uri) { +		// For this sample, assume all files are .apks. +		return "application/octet-stream"; +	} + +	@Override +	public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException { +		File dumpfile = getFileFromURI(uri); + +		try { + +			InputStream is = new FileInputStream(dumpfile); +			// Start a new thread that pipes the stream data back to the caller. +			return new AssetFileDescriptor( +					openPipeHelper(uri, null, null, is, this), 0, +					dumpfile.length()); +		} catch (IOException e) { +			FileNotFoundException fnf = new FileNotFoundException("Unable to open minidump " + uri); +			throw fnf; +		} +	} + +	private File getFileFromURI(Uri uri) throws FileNotFoundException { +		// Try to open an asset with the given name. +		String path = uri.getPath(); +		if(path.startsWith("/")) +			path = path.replaceFirst("/", "");        + +		// I think this already random enough, no need for magic secure cookies +		// 1f9563a4-a1f5-2165-255f2219-111823ef.dmp +		if (!path.matches("^[0-9a-z-.]*(dmp|dmp.log)$")) +			throw new FileNotFoundException("url not in expect format " + uri); +		File cachedir = getContext().getCacheDir(); +		File dumpfile = new File(cachedir,path); +		return dumpfile; +	} + +	@Override +	public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String mimeType, +			Bundle opts, InputStream args) { +		// Transfer data from the asset to the pipe the client is reading. +		byte[] buffer = new byte[8192]; +		int n; +		FileOutputStream fout = new FileOutputStream(output.getFileDescriptor()); +		try { +			while ((n=args.read(buffer)) >= 0) { +				fout.write(buffer, 0, n); +			} +		} catch (IOException e) { +			Log.i("OpenVPNFileProvider", "Failed transferring", e); +		} finally { +			try { +				args.close(); +			} catch (IOException e) { +			} +			try { +				fout.close(); +			} catch (IOException e) { +			} +		} +	}  } diff --git a/src/de/blinkt/openvpn/LogWindow.java b/src/de/blinkt/openvpn/LogWindow.java index 3c0f7246..790e143a 100644 --- a/src/de/blinkt/openvpn/LogWindow.java +++ b/src/de/blinkt/openvpn/LogWindow.java @@ -1,9 +1,5 @@  package de.blinkt.openvpn; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.ArrayList;  import java.util.Vector;  import android.app.AlertDialog; @@ -16,7 +12,6 @@ import android.content.DialogInterface;  import android.content.DialogInterface.OnClickListener;  import android.content.Intent;  import android.database.DataSetObserver; -import android.net.Uri;  import android.os.Bundle;  import android.os.Handler;  import android.os.Handler.Callback; @@ -227,8 +222,6 @@ public class LogWindow extends ListActivity implements StateListener  {  		} else if(item.getItemId()==R.id.info) {  			if(mBconfig==null)  				OpenVPN.triggerLogBuilderConfig(); -		} else if(item.getItemId()==R.id.minidump) { -			emailMiniDumps();  		} else if(item.getItemId()==R.id.send) {  			ladapter.shareLog(); @@ -258,72 +251,9 @@ public class LogWindow extends ListActivity implements StateListener  {  	public boolean onCreateOptionsMenu(Menu menu) {  		MenuInflater inflater = getMenuInflater();  		inflater.inflate(R.menu.logmenu, menu); -		 -		 -		 -		if(getLastestDump()==null) -			menu.removeItem(R.id.minidump); -		  		return true;  	} -	private File getLastestDump() { -		long newestDumpTime=0; -		File newestDumpFile=null; - -		for(File f:getCacheDir().listFiles()) { -			if(!f.getName().endsWith(".dmp")) -				continue; - -			if (newestDumpTime < f.lastModified()) { -				newestDumpTime = f.lastModified(); -				newestDumpFile=f; -			} -		} -		return newestDumpFile; -	} - - -	public void emailMiniDumps() -	{ -		//need to "send multiple" to get more than one attachment -		final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE); -		emailIntent.setType("*/*"); -		emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,  -				new String[]{"Arne Schwabe <arne@rfc2549.org>"}); -		emailIntent.putExtra(Intent.EXTRA_SUBJECT, "OpenVPN Minidump"); - -		 -		ArrayList<CharSequence> textarraylist = new ArrayList<CharSequence>(); -		textarraylist.add("Please describe the issue you have experienced"); -		emailIntent.putExtra(Intent.EXTRA_TEXT, textarraylist); - - -		ArrayList<Uri> uris = new ArrayList<Uri>(); - -		File ldump = getLastestDump(); -		if(ldump==null) { -			OpenVPN.logError("No Minidump found!"); -		} -		 -		uris.add(Uri.parse("content://de.blinkt.openvpn.FileProvider/" + ldump.getName())); -		uris.add(Uri.parse("content://de.blinkt.openvpn.FileProvider/openvpn.log")); -		 -		 -		try { -			FileWriter logout = new FileWriter(new File(getCacheDir(),"openvpn.log")); -			logout.write(ladapter.getLogStr()); -			logout.close(); - -		} catch (IOException e1) { -			OpenVPN.logError("Error writing log: " + e1.getLocalizedMessage()); -		} -		 -		//emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); -		emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); -		startActivity(emailIntent); -	} -  	@Override  	protected void onResume() { diff --git a/src/de/blinkt/openvpn/MainActivity.java b/src/de/blinkt/openvpn/MainActivity.java index 9b329817..32cf575b 100644 --- a/src/de/blinkt/openvpn/MainActivity.java +++ b/src/de/blinkt/openvpn/MainActivity.java @@ -1,8 +1,11 @@  package de.blinkt.openvpn; +import java.io.File; +import java.util.ArrayList;  import java.util.List;  import android.content.Intent; +import android.net.Uri;  import android.preference.PreferenceActivity;  public class MainActivity extends PreferenceActivity { @@ -19,6 +22,15 @@ public class MainActivity extends PreferenceActivity {  			translation.summary = translatedby;  			target.add(translation);  		} +		 +		if(SendDumpActivity.getLastestDump(this)!=null) { +			Header sendDump = new Header(); +			sendDump.titleRes = R.string.send_minidump; +			sendDump.summaryRes = R.string.send_minidump_summary; +			sendDump.intent = new Intent(this,SendDumpActivity.class); +			target.add(sendDump); +		} +		  	}  	@Override @@ -29,4 +41,6 @@ public class MainActivity extends PreferenceActivity {  	} + +  } diff --git a/src/de/blinkt/openvpn/OpenVPN.java b/src/de/blinkt/openvpn/OpenVPN.java index 48623865..0ae681bc 100644 --- a/src/de/blinkt/openvpn/OpenVPN.java +++ b/src/de/blinkt/openvpn/OpenVPN.java @@ -7,10 +7,10 @@ import android.content.Context;  import android.os.Build;  public class OpenVPN { -	 +  	public static LinkedList<LogItem> logbuffer; -	 +  	private static Vector<LogListener> logListener;  	private static Vector<StateListener> stateListener;  	private static String[] mBconfig; @@ -18,14 +18,14 @@ public class OpenVPN {  	private static String mLaststatemsg;  	private static String mLaststate; -	 +  	static {  		logbuffer  = new LinkedList<LogItem>();  		logListener = new Vector<OpenVPN.LogListener>();  		stateListener = new Vector<OpenVPN.StateListener>();  		logInformation();  	} -	 +  	static class LogItem {  		public static final int ERROR = 1;  		public static final int INFO = 2; @@ -36,20 +36,20 @@ public class OpenVPN {  		private int mRessourceId;  		// Default log priority  		int mLevel = INFO; -		 +  		public LogItem(int ressourceId, Object[] args) { -		 mRessourceId = ressourceId; -		 mArgs = args; +			mRessourceId = ressourceId; +			mArgs = args;  		} -		 +  		public LogItem(int loglevel,int ressourceId, Object[] args) { -			 mRessourceId = ressourceId; -			 mArgs = args; -			 mLevel = loglevel; -			} +			mRessourceId = ressourceId; +			mArgs = args; +			mLevel = loglevel; +		} + -		  		public LogItem(String message) {  			mMessage = message;  		} @@ -70,28 +70,32 @@ public class OpenVPN {  			if(mMessage !=null) {  				return mMessage;  			} else { -				if(mArgs == null) -					return c.getString(mRessourceId); -				else -					return c.getString(mRessourceId,mArgs); +				if(c!=null) { +					if(mArgs == null) +						return c.getString(mRessourceId); +					else +						return c.getString(mRessourceId,mArgs); +				} else { +					return String.format("Log (no context) resid %d", mRessourceId); +				}  			}  		}  	} -	 +  	private static final int MAXLOGENTRIES = 200;  	public static final String MANAGMENT_PREFIX = "M:"; -	 +  	public interface LogListener {  		void newLog(LogItem logItem);  	} -	 +  	public interface StateListener {  		void updateState(String state, String logmessage);  	} @@ -108,7 +112,7 @@ public class OpenVPN {  	}  	private static void logInformation() { -		 +  		logInfo(R.string.mobile_info,Build.MODEL, Build.BOARD,Build.BRAND,Build.VERSION.SDK_INT);  	} @@ -120,7 +124,7 @@ public class OpenVPN {  		logListener.remove(ll);  	} -	 +  	synchronized static void addStateListener(StateListener sl){  		stateListener.add(sl);  		if(mLaststate!=null) @@ -156,7 +160,7 @@ public class OpenVPN {  	public synchronized static void updateStateString(String state, String msg) {  		mLaststate= state;  		mLaststatemsg = msg; -		 +  		for (StateListener sl : stateListener) {  			sl.updateState(state,msg);  		} @@ -174,7 +178,7 @@ public class OpenVPN {  		logbuffer.addLast(logItem);  		if(logbuffer.size()>MAXLOGENTRIES)  			logbuffer.removeFirst(); -		 +  		for (LogListener ll : logListener) {  			ll.newLog(logItem);  		} @@ -182,7 +186,7 @@ public class OpenVPN {  	public static void logError(String msg) {  		newlogItem(new LogItem(LogItem.ERROR, msg)); -		 +  	}  	public static void logError(int ressourceId) { @@ -191,6 +195,6 @@ public class OpenVPN {  	public static void logError(int ressourceId, Object... args) {  		newlogItem(new LogItem(LogItem.ERROR, ressourceId,args));  	} -	 -	 + +  } diff --git a/src/de/blinkt/openvpn/OpenVPNThread.java b/src/de/blinkt/openvpn/OpenVPNThread.java index 13b8688b..7d58552a 100644 --- a/src/de/blinkt/openvpn/OpenVPNThread.java +++ b/src/de/blinkt/openvpn/OpenVPNThread.java @@ -1,19 +1,24 @@  package de.blinkt.openvpn;
  import java.io.BufferedReader;
 +import java.io.BufferedWriter;
 +import java.io.FileWriter;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.util.LinkedList;
  import android.util.Log;
 +import de.blinkt.openvpn.OpenVPN.LogItem;
  public class OpenVPNThread implements Runnable {
 +	private static final String DUMP_PATH_STRING = "Dump path: ";
  	private static final String TAG = "OpenVPN";
  	private String[] mArgv;
  	private Process mProcess;
  	private String mNativeDir;
  	private OpenVpnService mService;
 +	private String mDumpPath;
  	public OpenVPNThread(OpenVpnService service,String[] argv, String nativelibdir)
  	{
 @@ -49,7 +54,18 @@ public class OpenVPNThread implements Runnable {  				OpenVPN.logError("Process exited with exit value " + exitvalue);
  			OpenVPN.updateStateString("NOPROCESS","No process running.");
 -
 +			if(mDumpPath!=null) {
 +				try {
 +					BufferedWriter logout = new BufferedWriter(new FileWriter(mDumpPath + ".log"));
 +					for(LogItem li :OpenVPN.getlogbuffer()){
 +						logout.write(li.getString(null) + "\n");
 +					}
 +					logout.close();
 +					OpenVPN.logError(R.string.minidump_generated);
 +				} catch (IOException e) {
 +					OpenVPN.logError("Writing minidump log: " +e.getLocalizedMessage());
 +				}
 +			}
  			mService.processDied();
  			Log.i(TAG, "Exiting");
 @@ -89,6 +105,9 @@ public class OpenVPNThread implements Runnable {  			while(true) {
  				String logline = br.readLine();
 +				if (logline.startsWith(DUMP_PATH_STRING))
 +					mDumpPath = logline.substring(DUMP_PATH_STRING.length());
 +					
  				if(logline==null) {
  					return;
  				}
 diff --git a/src/de/blinkt/openvpn/OpenVpnManagementThread.java b/src/de/blinkt/openvpn/OpenVpnManagementThread.java index d15e6a33..9926ba13 100644 --- a/src/de/blinkt/openvpn/OpenVpnManagementThread.java +++ b/src/de/blinkt/openvpn/OpenVpnManagementThread.java @@ -39,7 +39,8 @@ public class OpenVpnManagementThread implements Runnable {  	private long mLastOut=0;
  	private LocalServerSocket mServerSocket;
  	private boolean mReleaseHold=true;
 -	private boolean mWaitingForRelease=false; 
 +	private boolean mWaitingForRelease=false;
 +	private long mLastHoldRelease=0; 
  	private static Vector<OpenVpnManagementThread> active=new Vector<OpenVpnManagementThread>();
 @@ -223,8 +224,15 @@ public class OpenVpnManagementThread implements Runnable {  		}
  	}
  	private void releaseHoldCmd() {
 +		if ((System.currentTimeMillis()- mLastHoldRelease) < 5000) {
 +			try {
 +				Thread.sleep(3000);
 +			} catch (InterruptedException e) {}
 +			
 +		}
  		mWaitingForRelease=false;
  		mReleaseHold=true;
 +		mLastHoldRelease  = System.currentTimeMillis();
  		managmentCommand("hold release\n");
  		managmentCommand("bytecount " + mBytecountinterval + "\n");
  		managmentCommand("state on\n");
 diff --git a/src/de/blinkt/openvpn/SendDumpActivity.java b/src/de/blinkt/openvpn/SendDumpActivity.java new file mode 100644 index 00000000..8a09b535 --- /dev/null +++ b/src/de/blinkt/openvpn/SendDumpActivity.java @@ -0,0 +1,60 @@ +package de.blinkt.openvpn; + +import java.io.File; +import java.util.ArrayList; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; + +public class SendDumpActivity extends Activity { +	 +	protected void onStart() { +		super.onStart(); +		emailMiniDumps(); +		finish(); +	}; +	 +	public void emailMiniDumps() +	{ +		//need to "send multiple" to get more than one attachment +		final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE); +		emailIntent.setType("*/*"); +		emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,  +				new String[]{"Arne Schwabe <arne@rfc2549.org>"}); +		emailIntent.putExtra(Intent.EXTRA_SUBJECT, "OpenVPN Minidump"); + +		emailIntent.putExtra(Intent.EXTRA_TEXT, "Please describe the issue you have experienced"); + +		ArrayList<Uri> uris = new ArrayList<Uri>(); + +		File ldump = getLastestDump(this); +		if(ldump==null) { +			OpenVPN.logError("No Minidump found!"); +		} +		 +		uris.add(Uri.parse("content://de.blinkt.openvpn.FileProvider/" + ldump.getName())); +		uris.add(Uri.parse("content://de.blinkt.openvpn.FileProvider/" + ldump.getName() + ".log")); + +		emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); +		emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris); +		startActivity(emailIntent); +	} + +	static public File getLastestDump(Context c) { +		long newestDumpTime=0; +		File newestDumpFile=null; + +		for(File f:c.getCacheDir().listFiles()) { +			if(!f.getName().endsWith(".dmp")) +				continue; + +			if (newestDumpTime < f.lastModified()) { +				newestDumpTime = f.lastModified(); +				newestDumpFile=f; +			} +		} +		return newestDumpFile; +	} +} | 
