1package eu.siacs.conversations.utils;
2
3import java.io.BufferedReader;
4import java.io.FileInputStream;
5import java.io.FileNotFoundException;
6import java.io.IOException;
7import java.io.InputStreamReader;
8import java.util.List;
9
10import eu.siacs.conversations.Config;
11import eu.siacs.conversations.R;
12import eu.siacs.conversations.entities.Account;
13import eu.siacs.conversations.entities.Conversation;
14import eu.siacs.conversations.entities.Message;
15import eu.siacs.conversations.services.XmppConnectionService;
16import eu.siacs.conversations.xmpp.jid.InvalidJidException;
17import eu.siacs.conversations.xmpp.jid.Jid;
18
19import android.app.AlertDialog;
20import android.content.Context;
21import android.content.DialogInterface;
22import android.content.SharedPreferences;
23import android.content.DialogInterface.OnClickListener;
24import android.content.pm.PackageInfo;
25import android.content.pm.PackageManager;
26import android.content.pm.PackageManager.NameNotFoundException;
27import android.preference.PreferenceManager;
28import android.text.format.DateUtils;
29import android.util.Log;
30
31public class ExceptionHelper {
32 public static void init(Context context) {
33 if (!(Thread.getDefaultUncaughtExceptionHandler() instanceof ExceptionHandler)) {
34 Thread.setDefaultUncaughtExceptionHandler(new ExceptionHandler(
35 context));
36 }
37 }
38
39 public static void checkForCrash(Context context,
40 final XmppConnectionService service) {
41 try {
42 final SharedPreferences preferences = PreferenceManager
43 .getDefaultSharedPreferences(context);
44 boolean neverSend = preferences.getBoolean("never_send", false);
45 if (neverSend) {
46 return;
47 }
48 List<Account> accounts = service.getAccounts();
49 Account account = null;
50 for (int i = 0; i < accounts.size(); ++i) {
51 if (!accounts.get(i).isOptionSet(Account.OPTION_DISABLED)) {
52 account = accounts.get(i);
53 break;
54 }
55 }
56 if (account == null) {
57 return;
58 }
59 final Account finalAccount = account;
60 FileInputStream file = context.openFileInput("stacktrace.txt");
61 InputStreamReader inputStreamReader = new InputStreamReader(file);
62 BufferedReader stacktrace = new BufferedReader(inputStreamReader);
63 final StringBuilder report = new StringBuilder();
64 PackageManager pm = context.getPackageManager();
65 PackageInfo packageInfo = null;
66 try {
67 packageInfo = pm.getPackageInfo(context.getPackageName(), 0);
68 report.append("Version: " + packageInfo.versionName + '\n');
69 report.append("Last Update: "
70 + DateUtils.formatDateTime(context,
71 packageInfo.lastUpdateTime,
72 DateUtils.FORMAT_SHOW_TIME
73 | DateUtils.FORMAT_SHOW_DATE) + '\n');
74 } catch (NameNotFoundException e) {
75 }
76 String line;
77 while ((line = stacktrace.readLine()) != null) {
78 report.append(line);
79 report.append('\n');
80 }
81 file.close();
82 context.deleteFile("stacktrace.txt");
83 AlertDialog.Builder builder = new AlertDialog.Builder(context);
84 builder.setTitle(context.getString(R.string.crash_report_title));
85 builder.setMessage(context.getText(R.string.crash_report_message));
86 builder.setPositiveButton(context.getText(R.string.send_now),
87 new OnClickListener() {
88
89 @Override
90 public void onClick(DialogInterface dialog, int which) {
91
92 Log.d(Config.LOGTAG, "using account="
93 + finalAccount.getJid()
94 + " to send in stack trace");
95 Conversation conversation = null;
96 try {
97 conversation = service.findOrCreateConversation(finalAccount,
98 Jid.fromString("bugs@siacs.eu"), false);
99 } catch (final InvalidJidException ignored) {
100 }
101 Message message = new Message(conversation, report
102 .toString(), Message.ENCRYPTION_NONE);
103 service.sendMessage(message);
104 }
105 });
106 builder.setNegativeButton(context.getText(R.string.send_never),
107 new OnClickListener() {
108
109 @Override
110 public void onClick(DialogInterface dialog, int which) {
111 preferences.edit().putBoolean("never_send", true)
112 .apply();
113 }
114 });
115 builder.create().show();
116 } catch (final IOException ignored) {
117 }
118
119 }
120}