Prevent crash

pull/194/head
M66B 5 years ago
parent ae4948e1c1
commit 0842ce21c2

@ -267,190 +267,203 @@ public class Log {
} }
private static void setupBugsnag(final Context context) { private static void setupBugsnag(final Context context) {
// https://docs.bugsnag.com/platforms/android/sdk/ try {
com.bugsnag.android.Configuration config = // https://docs.bugsnag.com/platforms/android/sdk/
new com.bugsnag.android.Configuration("9d2d57476a0614974449a3ec33f2604a"); com.bugsnag.android.Configuration config =
new com.bugsnag.android.Configuration("9d2d57476a0614974449a3ec33f2604a");
if (BuildConfig.DEBUG) if (BuildConfig.DEBUG)
config.setReleaseStage("debug"); config.setReleaseStage("debug");
else { else {
String type; String type;
if (Helper.hasValidFingerprint(context)) { if (Helper.hasValidFingerprint(context)) {
if (BuildConfig.PLAY_STORE_RELEASE) if (BuildConfig.PLAY_STORE_RELEASE)
type = "play"; type = "play";
else else
type = "full"; type = "full";
} else { } else {
if (BuildConfig.APPLICATION_ID.startsWith("eu.faircode.email")) if (BuildConfig.APPLICATION_ID.startsWith("eu.faircode.email"))
type = "other"; type = "other";
else else
type = "clone"; type = "clone";
}
config.setReleaseStage(type + (BuildConfig.BETA_RELEASE ? "/beta" : ""));
} }
config.setReleaseStage(type + (BuildConfig.BETA_RELEASE ? "/beta" : ""));
}
config.setAutoTrackSessions(false); config.setAutoTrackSessions(false);
ErrorTypes etypes = new ErrorTypes(); ErrorTypes etypes = new ErrorTypes();
etypes.setAnrs(BuildConfig.DEBUG); etypes.setAnrs(BuildConfig.DEBUG);
etypes.setNdkCrashes(false); etypes.setNdkCrashes(false);
config.setEnabledErrorTypes(etypes); config.setEnabledErrorTypes(etypes);
Set<String> ignore = new HashSet<>(); Set<String> ignore = new HashSet<>();
ignore.add("com.sun.mail.util.MailConnectException"); ignore.add("com.sun.mail.util.MailConnectException");
ignore.add("android.accounts.AuthenticatorException"); ignore.add("android.accounts.AuthenticatorException");
ignore.add("android.accounts.OperationCanceledException"); ignore.add("android.accounts.OperationCanceledException");
ignore.add("android.app.RemoteServiceException"); ignore.add("android.app.RemoteServiceException");
ignore.add("java.lang.NoClassDefFoundError"); ignore.add("java.lang.NoClassDefFoundError");
ignore.add("java.lang.UnsatisfiedLinkError"); ignore.add("java.lang.UnsatisfiedLinkError");
ignore.add("java.nio.charset.MalformedInputException"); ignore.add("java.nio.charset.MalformedInputException");
ignore.add("java.net.ConnectException"); ignore.add("java.net.ConnectException");
ignore.add("java.net.SocketException"); ignore.add("java.net.SocketException");
ignore.add("java.net.SocketTimeoutException"); ignore.add("java.net.SocketTimeoutException");
ignore.add("java.net.UnknownHostException"); ignore.add("java.net.UnknownHostException");
ignore.add("javax.mail.AuthenticationFailedException"); ignore.add("javax.mail.AuthenticationFailedException");
ignore.add("javax.mail.internet.AddressException"); ignore.add("javax.mail.internet.AddressException");
ignore.add("javax.mail.internet.ParseException"); ignore.add("javax.mail.internet.ParseException");
ignore.add("javax.mail.MessageRemovedException"); ignore.add("javax.mail.MessageRemovedException");
ignore.add("javax.mail.FolderNotFoundException"); ignore.add("javax.mail.FolderNotFoundException");
ignore.add("javax.mail.ReadOnlyFolderException"); ignore.add("javax.mail.ReadOnlyFolderException");
ignore.add("javax.mail.FolderClosedException"); ignore.add("javax.mail.FolderClosedException");
ignore.add("com.sun.mail.util.FolderClosedIOException"); ignore.add("com.sun.mail.util.FolderClosedIOException");
ignore.add("javax.mail.StoreClosedException"); ignore.add("javax.mail.StoreClosedException");
ignore.add("org.xmlpull.v1.XmlPullParserException"); ignore.add("org.xmlpull.v1.XmlPullParserException");
config.setDiscardClasses(ignore); config.setDiscardClasses(ignore);
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
String no_internet = context.getString(R.string.title_no_internet);
String installer = context.getPackageManager().getInstallerPackageName(BuildConfig.APPLICATION_ID);
config.addMetadata("extra", "installer", installer == null ? "-" : installer);
config.addMetadata("extra", "installed", new Date(Helper.getInstallTime(context)).toString());
config.addMetadata("extra", "fingerprint", Helper.hasValidFingerprint(context));
config.addMetadata("extra", "memory_class", am.getMemoryClass());
config.addMetadata("extra", "memory_class_large", am.getLargeMemoryClass());
config.addOnSession(new OnSessionCallback() {
@Override
public boolean onSession(@NonNull Session session) {
// opt-in
return prefs.getBoolean("crash_reports", false);
}
});
config.addOnError(new OnErrorCallback() {
@Override
public boolean onError(@NonNull Event event) {
// opt-in
boolean crash_reports = prefs.getBoolean("crash_reports", false);
if (!crash_reports)
return false;
Throwable ex = event.getOriginalError(); final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean should = shouldNotify(ex); ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (should) { String no_internet = context.getString(R.string.title_no_internet);
event.addMetadata("extra", "thread", Thread.currentThread().getName() + ":" + Thread.currentThread().getId());
event.addMetadata("extra", "memory_free", getFreeMemMb());
event.addMetadata("extra", "memory_available", getAvailableMb());
Boolean ignoringOptimizations = Helper.isIgnoringOptimizations(context); String installer = context.getPackageManager().getInstallerPackageName(BuildConfig.APPLICATION_ID);
event.addMetadata("extra", "optimizing", (ignoringOptimizations != null && !ignoringOptimizations)); config.addMetadata("extra", "installer", installer == null ? "-" : installer);
config.addMetadata("extra", "installed", new Date(Helper.getInstallTime(context)).toString());
config.addMetadata("extra", "fingerprint", Helper.hasValidFingerprint(context));
config.addMetadata("extra", "memory_class", am.getMemoryClass());
config.addMetadata("extra", "memory_class_large", am.getLargeMemoryClass());
String theme = prefs.getString("theme", "blue_orange_system"); config.addOnSession(new OnSessionCallback() {
event.addMetadata("extra", "theme", theme); @Override
event.addMetadata("extra", "package", BuildConfig.APPLICATION_ID); public boolean onSession(@NonNull Session session) {
// opt-in
return prefs.getBoolean("crash_reports", false);
} }
});
config.addOnError(new OnErrorCallback() {
@Override
public boolean onError(@NonNull Event event) {
// opt-in
boolean crash_reports = prefs.getBoolean("crash_reports", false);
if (!crash_reports)
return false;
Throwable ex = event.getOriginalError();
boolean should = shouldNotify(ex);
if (should) {
event.addMetadata("extra", "thread", Thread.currentThread().getName() + ":" + Thread.currentThread().getId());
event.addMetadata("extra", "memory_free", getFreeMemMb());
event.addMetadata("extra", "memory_available", getAvailableMb());
Boolean ignoringOptimizations = Helper.isIgnoringOptimizations(context);
event.addMetadata("extra", "optimizing", (ignoringOptimizations != null && !ignoringOptimizations));
String theme = prefs.getString("theme", "blue_orange_system");
event.addMetadata("extra", "theme", theme);
event.addMetadata("extra", "package", BuildConfig.APPLICATION_ID);
}
return should; return should;
} }
private boolean shouldNotify(Throwable ex) {
if (ex instanceof MessagingException &&
(ex.getCause() instanceof IOException ||
ex.getCause() instanceof ProtocolException))
// IOException includes SocketException, SocketTimeoutException
// ProtocolException includes ConnectionException
return false;
if (ex instanceof MessagingException &&
("connection failure".equals(ex.getMessage()) ||
"failed to create new store connection".equals(ex.getMessage()) ||
"Failed to fetch headers".equals(ex.getMessage()) ||
"Failed to load IMAP envelope".equals(ex.getMessage()) ||
"Unable to load BODYSTRUCTURE".equals(ex.getMessage())))
return false;
if (ex instanceof IllegalStateException &&
(no_internet.equals(ex.getMessage()) ||
"Not connected".equals(ex.getMessage()) ||
"This operation is not allowed on a closed folder".equals(ex.getMessage())))
return false;
if (ex instanceof FileNotFoundException &&
ex.getMessage() != null &&
(ex.getMessage().startsWith("Download image failed") ||
ex.getMessage().startsWith("http://") ||
ex.getMessage().startsWith("https://") ||
ex.getMessage().startsWith("content://")))
return false;
if (ex instanceof IOException &&
ex.getCause() instanceof MessageRemovedException)
return false;
if (ex instanceof IOException &&
ex.getMessage() != null &&
(ex.getMessage().startsWith("HTTP status=") ||
"NetworkError".equals(ex.getMessage()) || // account manager
"Resetting to invalid mark".equals(ex.getMessage()) ||
"Mark has been invalidated.".equals(ex.getMessage())))
return false;
if (ex instanceof SSLPeerUnverifiedException ||
ex instanceof EmailService.UntrustedException)
return false;
if (ex instanceof SSLHandshakeException && private boolean shouldNotify(Throwable ex) {
ex.getCause() instanceof CertPathValidatorException) if (ex instanceof MessagingException &&
return false; // checkUpdate! (ex.getCause() instanceof IOException ||
ex.getCause() instanceof ProtocolException))
// IOException includes SocketException, SocketTimeoutException
// ProtocolException includes ConnectionException
return false;
if (ex instanceof MessagingException &&
("connection failure".equals(ex.getMessage()) ||
"failed to create new store connection".equals(ex.getMessage()) ||
"Failed to fetch headers".equals(ex.getMessage()) ||
"Failed to load IMAP envelope".equals(ex.getMessage()) ||
"Unable to load BODYSTRUCTURE".equals(ex.getMessage())))
return false;
if (ex instanceof IllegalStateException &&
(no_internet.equals(ex.getMessage()) ||
"Not connected".equals(ex.getMessage()) ||
"This operation is not allowed on a closed folder".equals(ex.getMessage())))
return false;
if (ex instanceof FileNotFoundException &&
ex.getMessage() != null &&
(ex.getMessage().startsWith("Download image failed") ||
ex.getMessage().startsWith("http://") ||
ex.getMessage().startsWith("https://") ||
ex.getMessage().startsWith("content://")))
return false;
if (ex instanceof IOException &&
ex.getCause() instanceof MessageRemovedException)
return false;
if (ex instanceof IOException &&
ex.getMessage() != null &&
(ex.getMessage().startsWith("HTTP status=") ||
"NetworkError".equals(ex.getMessage()) || // account manager
"Resetting to invalid mark".equals(ex.getMessage()) ||
"Mark has been invalidated.".equals(ex.getMessage())))
return false;
if (ex instanceof SSLPeerUnverifiedException ||
ex instanceof EmailService.UntrustedException)
return false;
if (ex instanceof SSLHandshakeException &&
ex.getCause() instanceof CertPathValidatorException)
return false; // checkUpdate!
if (ex instanceof RuntimeException &&
"Illegal meta data value: the child service doesn't exist".equals(ex.getMessage()))
return false;
// Rate limit
int count = prefs.getInt("crash_report_count", 0) + 1;
prefs.edit().putInt("crash_report_count", count).apply();
return (count <= MAX_CRASH_REPORTS);
}
});
if (ex instanceof RuntimeException && Bugsnag.start(context, config);
"Illegal meta data value: the child service doesn't exist".equals(ex.getMessage()))
return false;
// Rate limit Client client = Bugsnag.getClient();
int count = prefs.getInt("crash_report_count", 0) + 1;
prefs.edit().putInt("crash_report_count", count).apply();
return (count <= MAX_CRASH_REPORTS); String uuid = prefs.getString("uuid", null);
if (uuid == null) {
uuid = UUID.randomUUID().toString();
prefs.edit().putString("uuid", uuid).apply();
} }
}); Log.i("uuid=" + uuid);
client.setUser(uuid, null, null);
Bugsnag.start(context, config);
Client client = Bugsnag.getClient(); if (prefs.getBoolean("crash_reports", false))
Bugsnag.startSession();
String uuid = prefs.getString("uuid", null); } catch (Throwable ex) {
if (uuid == null) { Log.e(ex);
uuid = UUID.randomUUID().toString(); /*
prefs.edit().putString("uuid", uuid).apply(); java.lang.AssertionError: No NameTypeIndex match for SHORT_DAYLIGHT
at android.icu.impl.TimeZoneNamesImpl$ZNames.getNameTypeIndex(TimeZoneNamesImpl.java:724)
at android.icu.impl.TimeZoneNamesImpl$ZNames.getName(TimeZoneNamesImpl.java:790)
at android.icu.impl.TimeZoneNamesImpl.getTimeZoneDisplayName(TimeZoneNamesImpl.java:183)
at android.icu.text.TimeZoneNames.getDisplayName(TimeZoneNames.java:261)
at java.util.TimeZone.getDisplayName(TimeZone.java:405)
at java.util.Date.toString(Date.java:1066)
*/
} }
Log.i("uuid=" + uuid);
client.setUser(uuid, null, null);
if (prefs.getBoolean("crash_reports", false))
Bugsnag.startSession();
} }
static void logExtras(Intent intent) { static void logExtras(Intent intent) {

Loading…
Cancel
Save