diff options
author | Kenny Root <kenny@the-b.org> | 2009-06-10 08:27:58 +0000 |
---|---|---|
committer | Kenny Root <kenny@the-b.org> | 2009-06-10 08:27:58 +0000 |
commit | d62e6eebae78c8d59c46517fd5cea9be6942f5ba (patch) | |
tree | 620ce7a5e365d71097bb839fcfa2f81890a6a234 /src/com/nullwire/trace/ExceptionHandler.java | |
parent | e7e79db923cd98bfd804ae2dc8383d949b5ddddb (diff) | |
download | connectbot-d62e6eebae78c8d59c46517fd5cea9be6942f5ba.tar.gz connectbot-d62e6eebae78c8d59c46517fd5cea9be6942f5ba.tar.bz2 connectbot-d62e6eebae78c8d59c46517fd5cea9be6942f5ba.zip |
Add stack trace reporting
* When an unhandled exception occurs, the exception handler writes it to a file in addition to all ther other stuff that normally happens
* The next time ConnectBot is started up, the user is prompted as to whether they want to submit the stack trace to aid in finding bugs.
* If the user agrees or declines, the stack traces are deleted.
git-svn-id: https://connectbot.googlecode.com/svn/trunk/connectbot@277 df292f66-193f-0410-a5fc-6d59da041ff2
Diffstat (limited to 'src/com/nullwire/trace/ExceptionHandler.java')
-rw-r--r-- | src/com/nullwire/trace/ExceptionHandler.java | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/src/com/nullwire/trace/ExceptionHandler.java b/src/com/nullwire/trace/ExceptionHandler.java new file mode 100644 index 0000000..b73ea86 --- /dev/null +++ b/src/com/nullwire/trace/ExceptionHandler.java @@ -0,0 +1,191 @@ +package com.nullwire.trace; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.FilenameFilter; +import java.util.ArrayList; +import java.util.List; + +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.DefaultHttpClient; +import org.apache.http.message.BasicNameValuePair; +import org.apache.http.protocol.HTTP; +import org.connectbot.R; + +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.util.Log; + +public class ExceptionHandler { + + public static String TAG = "com.nullwire.trace.ExceptionsHandler"; + + private static String[] stackTraceFileList = null; + + private static AlertDialog submitDialog; + + /** + * @param context + */ + public static void checkForTraces(Context context) { + if (searchForStackTraces(context).length > 0) { + Log.d(TAG, "number of stack traces: " + searchForStackTraces(context).length); + askUserToSubmitExceptions(context); + } + } + + /** + * @param context + */ + private static void getPackageInfo(Context context) { + // Get information about the Package + PackageManager pm = context.getPackageManager(); + try { + PackageInfo pi; + // Version + pi = pm.getPackageInfo(context.getPackageName(), 0); + G.APP_VERSION = pi.versionName; + // Package name + G.APP_PACKAGE = pi.packageName; + // Files dir for storing the stack traces + G.FILES_PATH = context.getFilesDir().getAbsolutePath(); + } catch (NameNotFoundException e) { + e.printStackTrace(); + } + + Log.d(TAG, "APP_VERSION: " + G.APP_VERSION); + Log.d(TAG, "APP_PACKAGE: " + G.APP_PACKAGE); + Log.d(TAG, "FILES_PATH: " + G.FILES_PATH); + Log.d(TAG, "URL: " + G.URL); + } + + public static void register(Context context) { + Log.i(TAG, "Registering default exceptions handler"); + + new Thread() { + @Override + public void run() { + // Register default exceptions handler + Thread.setDefaultUncaughtExceptionHandler(new DefaultExceptionHandler()); + } + }.start(); + } + + /** + * Search for stack trace files. + * + * @return + */ + private static String[] searchForStackTraces(Context context) { + if (stackTraceFileList != null && stackTraceFileList.length > 0) + return stackTraceFileList; + + if (G.FILES_PATH == null) + getPackageInfo(context); + + File dir = new File(G.FILES_PATH + "/"); + // Try to create the files folder if it doesn't exist + dir.mkdir(); + // Filter for ".stacktrace" files + FilenameFilter filter = new FilenameFilter() { + public boolean accept(File dir, String name) { + return name.endsWith(".stacktrace"); + } + }; + return (stackTraceFileList = dir.list(filter)); + } + + public static void askUserToSubmitExceptions(Context context) { + if (submitDialog == null) { + DialogInterface.OnClickListener clickListener = new ExceptionClickListener(context); + submitDialog = new AlertDialog.Builder(context) + .setMessage(R.string.exceptions_submit_message) + .setPositiveButton(android.R.string.ok, clickListener) + .setNegativeButton(android.R.string.no, clickListener) + .create(); + } + + submitDialog.show(); + } + + /** + * Look into the files folder to see if there are any "*.stacktrace" files. + * If any are present, submit them to the trace server. + */ + public static void submitStackTraces(Context context) { + try { + Log.d(TAG, "Looking for exceptions in: " + G.FILES_PATH); + String[] list = searchForStackTraces(context); + if (list != null && list.length > 0) { + Log.d(TAG, "Found " + list.length + " stacktrace(s)"); + StringBuilder contents = new StringBuilder(); + for (int i = 0; i < list.length; i++) { + String filePath = G.FILES_PATH + "/" + list[i]; + // Extract the version from the filename: + // "packagename-version-...." + String version = list[i].split("-")[0]; + Log.d(TAG, "Stacktrace in file '" + filePath + + "' belongs to version " + version); + // Read contents of stacktrace + contents.setLength(0); + BufferedReader input; + try { + input = new BufferedReader(new FileReader(filePath)); + } catch (FileNotFoundException fnf) { + continue; + } + String line = null; + while ((line = input.readLine()) != null) { + contents.append(line); + contents.append(System.getProperty("line.separator")); + } + input.close(); + String stacktrace; + stacktrace = contents.toString(); + Log.d(TAG, "Transmitting stack trace: " + stacktrace); + // Transmit stack trace with POST request + DefaultHttpClient httpClient = new DefaultHttpClient(); + HttpPost httpPost = new HttpPost(G.URL); + List<NameValuePair> nvps = new ArrayList<NameValuePair>(); + nvps.add(new BasicNameValuePair("package_name", G.APP_PACKAGE)); + nvps.add(new BasicNameValuePair("package_version", version)); + nvps.add(new BasicNameValuePair("stacktrace", stacktrace)); + httpPost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8)); + // We don't care about the response, so we just hope it went + // well and on with it + httpClient.execute(httpPost); + } + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + removeStackTraces(context); + } + } + + public synchronized static void removeStackTraces(Context context) { + try { + String[] list = searchForStackTraces(context); + + if (list == null) + return; + + for (int i = 0; i < list.length; i++) { + File file = new File(G.FILES_PATH + "/" + list[i]); + file.delete(); + } + + list = null; + } catch (Exception e) { + e.printStackTrace(); + } + } +} |