crash reporter

Daniel Gultsch created

Change summary

res/values/strings.xml                                  |  4 
res/xml/preferences.xml                                 |  8 +
src/eu/siacs/conversations/ui/ConversationActivity.java |  2 
src/eu/siacs/conversations/utils/ExceptionHelper.java   | 80 +++++++++++
4 files changed, 94 insertions(+)

Detailed changes

res/values/strings.xml πŸ”—

@@ -40,4 +40,8 @@
     <string name="invitation_sent">Invitation sent</string>
     <string name="account_offline">Account offline</string>
     <string name="cant_invite_while_offline">You have to be online to invite people to conferences</string>
+    <string name="crash_report_title">Conversations has crashed</string>
+    <string name="crash_report_message">By sending in stack traces you are helping the ongoing development of Conversations\n<b>Warning:</b> This will use your XMPP account to send the stack trace to the developer.</string>
+    <string name="send_now">Send now</string>
+    <string name="send_never">Never ask again</string>
 </resources>

res/xml/preferences.xml πŸ”—

@@ -55,4 +55,12 @@
             android:summary="Use room’s subject to identify Conferences"
             android:defaultValue="true"/>
     </PreferenceCategory>
+    <PreferenceCategory
+        android:title="Advanced Options">
+        <CheckBoxPreference 
+            android:key="never_send"
+            android:title="Never send crash reports"
+            android:summary="By sending in stack traces you are helping the ongoing development of Conversations"
+            android:defaultValue="false"/>
+    </PreferenceCategory>
 </PreferenceScreen>

src/eu/siacs/conversations/ui/ConversationActivity.java πŸ”—

@@ -8,6 +8,7 @@ import eu.siacs.conversations.entities.Account;
 import eu.siacs.conversations.entities.Contact;
 import eu.siacs.conversations.entities.Conversation;
 import eu.siacs.conversations.entities.Message;
+import eu.siacs.conversations.utils.ExceptionHelper;
 import eu.siacs.conversations.utils.UIHelper;
 import android.os.Bundle;
 import android.preference.PreferenceManager;
@@ -454,6 +455,7 @@ public class ConversationActivity extends XmppActivity {
 					selectedConversation = conversationList.get(0);
 					swapConversationFragment();
 				}
+				ExceptionHelper.checkForCrash(this,this.xmppConnectionService);
 			}
 		}
 	}

src/eu/siacs/conversations/utils/ExceptionHelper.java πŸ”—

@@ -1,6 +1,25 @@
 package eu.siacs.conversations.utils;
 
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.util.List;
+
+import eu.siacs.conversations.R;
+import eu.siacs.conversations.entities.Account;
+import eu.siacs.conversations.entities.Conversation;
+import eu.siacs.conversations.entities.Message;
+import eu.siacs.conversations.services.XmppConnectionService;
+import android.app.AlertDialog;
 import android.content.Context;
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+import android.content.DialogInterface.OnClickListener;
+import android.preference.PreferenceManager;
+import android.util.Log;
 
 public class ExceptionHelper {
 	public static void init(Context context) {
@@ -8,4 +27,65 @@ public class ExceptionHelper {
 		    Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(context));
 		}
 	}
+	
+	public static void checkForCrash(Context context, final XmppConnectionService service) {
+		try {
+			final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(context);
+			boolean neverSend = preferences.getBoolean("never_send",false);
+			if (neverSend) {
+				return;
+			}
+			FileInputStream file = context.openFileInput("stacktrace.txt");
+			InputStreamReader inputStreamReader = new InputStreamReader(
+                    file);
+            BufferedReader bufferedReader = new BufferedReader(
+                    inputStreamReader);
+            final StringBuilder stacktrace = new StringBuilder();
+            String line;
+            while((line = bufferedReader.readLine()) != null) {
+            	stacktrace.append(line);
+            	stacktrace.append('\n');
+            }
+            file.close();
+            context.deleteFile("stacktrace.txt");
+			AlertDialog.Builder builder = new AlertDialog.Builder(context);
+			builder.setTitle(context.getString(R.string.crash_report_title));
+			builder.setMessage(context.getText(R.string.crash_report_message));
+			builder.setPositiveButton(context.getText(R.string.send_now), new OnClickListener() {
+				
+				@Override
+				public void onClick(DialogInterface dialog, int which) {
+					List<Account> accounts = service.getAccounts();
+					Account account = null;
+					for(int i = 0; i < accounts.size(); ++i) {
+						if (!accounts.get(i).isOptionSet(Account.OPTION_DISABLED)) {
+							account = accounts.get(i);
+							break;
+						}
+					}
+					if (account!=null) {
+						Log.d("xmppService","using account="+account.getJid()+" to send in stack trace");
+						Conversation conversation = service.findOrCreateConversation(account, "bugs@siacs.eu", false);
+						Message message = new Message(conversation, stacktrace.toString(), Message.ENCRYPTION_NONE);
+						service.sendMessage(message, null);
+					}
+				}
+			});
+			builder.setNegativeButton(context.getText(R.string.send_never),new OnClickListener() {
+				
+				@Override
+				public void onClick(DialogInterface dialog, int which) {
+					preferences.edit().putBoolean("never_send", true).commit();
+				}
+			});
+			builder.create().show();
+		} catch (FileNotFoundException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		
+	}
 }