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); + } + +}