From 23a900c433b55d5376dbbe4dd0221140b05947c5 Mon Sep 17 00:00:00 2001 From: agnostic-apollo Date: Thu, 1 Jul 2021 04:21:02 +0500 Subject: [PATCH] Move Termux app specific logic out of CrashHandler Create the TermuxCrashUtils class that provides the default path and app for termux instead of hardcoding it in CrashHandler. TermuxCrashUtils can be used by termux plugins as well for their own usage or they can implement the CrashHandler.CrashHandlerClient if they want to log to different files or want custom logic. --- .../com/termux/app/TermuxApplication.java | 4 +- .../com/termux/shared/crash/CrashHandler.java | 53 ++++++++++++++----- .../termux/shared/crash/TermuxCrashUtils.java | 31 +++++++++++ 3 files changed, 72 insertions(+), 16 deletions(-) create mode 100644 termux-shared/src/main/java/com/termux/shared/crash/TermuxCrashUtils.java diff --git a/app/src/main/java/com/termux/app/TermuxApplication.java b/app/src/main/java/com/termux/app/TermuxApplication.java index beb66634..b7f28980 100644 --- a/app/src/main/java/com/termux/app/TermuxApplication.java +++ b/app/src/main/java/com/termux/app/TermuxApplication.java @@ -2,7 +2,7 @@ package com.termux.app; import android.app.Application; -import com.termux.shared.crash.CrashHandler; +import com.termux.shared.crash.TermuxCrashUtils; import com.termux.shared.settings.preferences.TermuxAppSharedPreferences; import com.termux.shared.logger.Logger; @@ -12,7 +12,7 @@ public class TermuxApplication extends Application { super.onCreate(); // Set crash handler for the app - CrashHandler.setCrashHandler(this); + TermuxCrashUtils.setCrashHandler(this); // Set log level for the app setLogLevel(); diff --git a/termux-shared/src/main/java/com/termux/shared/crash/CrashHandler.java b/termux-shared/src/main/java/com/termux/shared/crash/CrashHandler.java index 8f5e028e..f7da618a 100644 --- a/termux-shared/src/main/java/com/termux/shared/crash/CrashHandler.java +++ b/termux-shared/src/main/java/com/termux/shared/crash/CrashHandler.java @@ -9,8 +9,6 @@ import com.termux.shared.logger.Logger; import com.termux.shared.markdown.MarkdownUtils; import com.termux.shared.models.errors.Error; import com.termux.shared.termux.AndroidUtils; -import com.termux.shared.termux.TermuxConstants; -import com.termux.shared.termux.TermuxUtils; import java.nio.charset.Charset; @@ -19,40 +17,41 @@ import java.nio.charset.Charset; */ public class CrashHandler implements Thread.UncaughtExceptionHandler { - private final Context context; + private final Context mContext; + private final CrashHandlerClient mCrashHandlerClient; private final Thread.UncaughtExceptionHandler defaultUEH; private static final String LOG_TAG = "CrashUtils"; - private CrashHandler(final Context context) { - this.context = context; + private CrashHandler(@NonNull final Context context, @NonNull final CrashHandlerClient crashHandlerClient) { + this.mContext = context; + this.mCrashHandlerClient = crashHandlerClient; this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler(); } public void uncaughtException(@NonNull Thread thread, @NonNull Throwable throwable) { - logCrash(context,thread, throwable); + logCrash(mContext, mCrashHandlerClient, thread, throwable); defaultUEH.uncaughtException(thread, throwable); } /** * Set default uncaught crash handler of current thread to {@link CrashHandler}. */ - public static void setCrashHandler(final Context context) { + public static void setCrashHandler(@NonNull final Context context, @NonNull final CrashHandlerClient crashHandlerClient) { if (!(Thread.getDefaultUncaughtExceptionHandler() instanceof CrashHandler)) { - Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(context)); + Thread.setDefaultUncaughtExceptionHandler(new CrashHandler(context, crashHandlerClient)); } } /** - * Log a crash in the crash log file at - * {@link TermuxConstants#TERMUX_CRASH_LOG_FILE_PATH}. + * Log a crash in the crash log file at {@code crashlogFilePath}. * * @param context The {@link Context} for operations. + * @param crashHandlerClient The {@link CrashHandlerClient} implementation. * @param thread The {@link Thread} in which the crash happened. * @param throwable The {@link Throwable} thrown for the crash. */ - public static void logCrash(final Context context, final Thread thread, final Throwable throwable) { - + public static void logCrash(@NonNull final Context context, @NonNull final CrashHandlerClient crashHandlerClient, final Thread thread, final Throwable throwable) { StringBuilder reportString = new StringBuilder(); reportString.append("## Crash Details\n"); @@ -60,17 +59,43 @@ public class CrashHandler implements Thread.UncaughtExceptionHandler { reportString.append("\n").append(MarkdownUtils.getSingleLineMarkdownStringEntry("Crash Timestamp", AndroidUtils.getCurrentTimeStamp(), "-")); reportString.append("\n\n").append(Logger.getStackTracesMarkdownString("Stacktrace", Logger.getStackTracesStringArray(throwable))); - reportString.append("\n\n").append(TermuxUtils.getAppInfoMarkdownString(context, true)); + + String appInfoMarkdownString = crashHandlerClient.getAppInfoMarkdownString(context); + if (appInfoMarkdownString != null && !appInfoMarkdownString.isEmpty()) + reportString.append("\n\n").append(appInfoMarkdownString); + reportString.append("\n\n").append(AndroidUtils.getDeviceInfoMarkdownString(context)); // Log report string to logcat Logger.logError(reportString.toString()); // Write report string to crash log file - Error error = FileUtils.writeStringToFile("crash log", TermuxConstants.TERMUX_CRASH_LOG_FILE_PATH, Charset.defaultCharset(), reportString.toString(), false); + Error error = FileUtils.writeStringToFile("crash log", crashHandlerClient.getCrashLogFilePath(context), + Charset.defaultCharset(), reportString.toString(), false); if (error != null) { Logger.logErrorExtended(LOG_TAG, error.toString()); } } + public interface CrashHandlerClient { + + /** + * Get crash log file path. + * + * @param context The {@link Context} passed to {@link CrashHandler#CrashHandler(Context, CrashHandlerClient)}. + * @return Should return the crash log file path. + */ + @NonNull + String getCrashLogFilePath(Context context); + + /** + * Get app info markdown string to add to crash log. + * + * @param context The {@link Context} passed to {@link CrashHandler#CrashHandler(Context, CrashHandlerClient)}. + * @return Should return app info markdown string. + */ + String getAppInfoMarkdownString(Context context); + + } + } diff --git a/termux-shared/src/main/java/com/termux/shared/crash/TermuxCrashUtils.java b/termux-shared/src/main/java/com/termux/shared/crash/TermuxCrashUtils.java new file mode 100644 index 00000000..d8b877fe --- /dev/null +++ b/termux-shared/src/main/java/com/termux/shared/crash/TermuxCrashUtils.java @@ -0,0 +1,31 @@ +package com.termux.shared.crash; + +import android.content.Context; + +import androidx.annotation.NonNull; + +import com.termux.shared.termux.TermuxConstants; +import com.termux.shared.termux.TermuxUtils; + +public class TermuxCrashUtils implements CrashHandler.CrashHandlerClient { + + /** + * Set default uncaught crash handler of current thread to {@link CrashHandler} for Termux app + * and its plugin to log crashes at {@link TermuxConstants#TERMUX_CRASH_LOG_FILE_PATH}. + */ + public static void setCrashHandler(@NonNull final Context context) { + CrashHandler.setCrashHandler(context, new TermuxCrashUtils()); + } + + @NonNull + @Override + public String getCrashLogFilePath(Context context) { + return TermuxConstants.TERMUX_CRASH_LOG_FILE_PATH; + } + + @Override + public String getAppInfoMarkdownString(Context context) { + return TermuxUtils.getAppInfoMarkdownString(context, true); + } + +}